% \iffalse % feynmf.dtx - Feynman diagrams with METAFONT for LaTeX(2e) % Copyright (C) 1989, 1990, 1992-1995 by Thorsten.Ohl@Physik.TH-Darmstadt.de % /home/sources/ohl/tex/thotex/feynmf/feynmf.dtx,v 1.10 1995/02/18 16:42:18 ohl Exp %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Feynmf is free software; you can redistribute it and/or modify it % under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2, or (at your option) % any later version. % Feynmf is distributed in the hope that it will be useful, but % WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \fi %% \CheckSum{553} %% \CharacterTable %% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z %% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z %% Digits \0\1\2\3\4\5\6\7\8\9 %% Exclamation \! Double quote \" Hash (number) \# %% Dollar \$ Percent \% Ampersand \& %% Acute accent \' Left paren \( Right paren \) %% Asterisk \* Plus \+ Comma \, %% Minus \- Point \. Solidus \/ %% Colon \: Semicolon \; Less than \< %% Equals \= Greater than \> Question mark \? %% Commercial at \@ Left bracket \[ Backslash \\ %% Right bracket \] Circumflex \^ Underscore \_ %% Grave accent \` Left brace \{ Vertical bar \| %% Right brace \} Tilde \~} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \MakeShortVerb{\|} % \title{% % \FMF: \\ % Drawing Feynman Diagrams \\ % with \LaTeX{} and \MF} % \author{% % Thorsten Ohl\thanks{e-mail: % {\tt Thorsten.Ohl@Physik.TH-Darmstadt.de}}\\ % \hfil \\ % Technische Hochschule Darmstadt \\ % Schlo\ss gartenstr. 9 \\ % D-64289 Darmstadt \\ % Germany} % \maketitle % \begin{abstract} % \FMF{} is a \LaTeX{} package for easy drawing of professional % quality Feynman diagrams with \MF. \FMF{} lays out most % diagrams satisfactorily from the structure of the graph without % any need for manual intervention. Nevertheless all the power of % \MF{} is available for the most obscure cases. % \end{abstract} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \section*{Copying} % \FMF{} is free software; you can redistribute it and/or modify it % under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2, or (at your option) % any later version. % \FMF{} is distributed in the hope that it will be useful, but % \emph{without any warranty}; without even the implied warranty of % \emph{merchantability} or \emph{fitness for a particular purpose}. % See the GNU General Public License for more details. % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \tableofcontents % \unitlength=1mm % \begin{fmffile}{fmfsampl} % \def\bottomfraction{0} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \section{Introduction} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Purpose and scope} % In recent years, \TeX\footnote{\TeX{} is a trademark of the American % Mathematical Society.}~\cite{TeX} % and \LaTeX\footnote{\LaTeX{} might be a trademark of Addison Wesley % Publishing Company.}~\cite{LaTeX} % have revolutionized the way % we share information in theoretical physics (and other areas). Not % only does \TeX{} provide typographical capabilities, which transcend % those of commercial ``wordprocessors'' substantially, \TeX{} documents % are also completely portable. Since implementations are available % on essentially all computers in use in the community, documents can % be shared without the usual restrictions of proprietary data % formats. This has enabled us to collaborate on papers with % colleagues on the other side of the globe, to replace the mailing of % hard copy preprints by electronic transmission and to submit these % papers electronically to the publisher. % This portability comes with a price, though. \TeX{} (and \LaTeX) % do not address the issue of graphical information, apart from the % rudimentary (but very useful) capabilities of the \LaTeX{} |picture| % environment and similar % packages~\cite{LaTeX-Companion}, which provide line drawings like % the one in figure~\ref{fig:flow}. As an de facto standard for the % inclusion of more complex graphics has emerged the inclusion of % PostScript~\footnote{PostScript is a trademark of Adobe Systems % Inc.} % files. The complete document can then % be printed on any PostScript device. % Still there are areas, where complementary approaches seem worth % pursuing. In particular this is the case, if the graphical % information is highly formalized, like the case at hand. Feynman % diagrams are specified by their topology and the type of particles % connecting the vertices. Thus a given diagram can be reproduced % from a very concise specification, if the software is able to choose % a reasonable layout (semi-)automatically. % \MF\footnote{\MF{} is a trademark of Addison Wesley Publishing % Company.}~\cite{MF} % and \MP\footnote{John Hobby's \MP{} is a modified version of \MF{} % which generates (encapsulated) PostScript output. \MP{} can be % build trivially on top of the \texttt{web2c} version of \TeX{} and % \MF{} for UNIX. Ports to other systems should be % simple.}~\cite{MetaPost} % appear to be the perfect tool for such a purpose, since % \begin{enumerate} % \item{} \MF{} is part of any (reasonable) \TeX{} installation, thus % available to all potential users, % \item{} both have very powerful graphics primitivs, which allow high % quality output, and % \item{} both have builtin linear algebra, which allows us to choose a % layout automatically. % \end{enumerate} % Still, providing at least the basic interface in \LaTeX{} macros % seems appropriate for boosting the acceptance among the less % technically oriented parts of the audience. Thus % \FMF\footnote{\FMF{} is not a trademark of anybody.} % was conceived. % \FMF{} supports \MF{} as well as \MP{} (under the names % \texttt{feynmp.sty} and \texttt{feynmp.mp}). % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Relation to similar packages} % Before we start, a couple of words about some complementary packages % on the market are in order. First of all: I failed to do my % homework and didn't try hard enough to find~\cite{hoenig} in a % library. I'm sure that in there is a smarter way of returning % information from \MF{} to \TeX{}. Those who don't know the % literature are doomed to reinvent the wheel. But this isn't a % scholarly work and reinventing the wheel was \emph{fun!} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsubsection{Feynman} % Micheal Levine's |feynman| package~\cite{levine} is % implemented on top of the standard \LaTeX{} |picture| % environment~\cite{LaTeX}. This makes it completely portable (no % need for a correct \MF{} installation), but it requires manual % layout and the graphics output is (though very useful) less than % perfect. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsubsection{Axodraw} % Jos Vermaseren's |axodraw| package~\cite{axodraw} uses % |\special|s to access PostScript primitives for drawing diagrams. % This approach is inherently not portable (though the ubiquity of % PostScript printers makes this a minor point) but at least as % flexible as the present one. It still requires manual layout, % though. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsubsection{Mfpic} % Last, but not least, I have to mention Thomas Leathrum's % |mfpic|~\cite{mfpic}, which was the main inspiration for moving % \FMF's user interface from \MF{} to \TeX. It might not have been % unreasonable to design and implement \FMF{} as a package on top of % |mfpic|\footnote{In fact a change in this direction would be rather % easy.}, % But closer inspection shows that \FMF{} and |mfpic| are fairly % orthogonal. |mfpic| is ideally suited for handling simple graphical % building blocks in formally unconstrained contexts, a task which will % be accomplished preferably by direct manual placement of objects. % \FMF{} on the other hand works in the highly formal context of % Feynman diagrams (or any other labeled graphs for that matter), % which can be draw automatically from a \emph{specification}. % It will of course be tempting to add more features from |mfpic|'s % realm to \FMF{} in the future, but I will try to be conservative in % that respect. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Historical note} % This code has a rather long history\footnote{Which is a partial % explanation, if not excuse, for its slightly incoherent structure.}. % Most of the sections~\ref{sec:mf-basics}, \ref{sec:pictures}, % \ref{sec:shading}, and~\ref{sec:drawing} started in 1989 as % |feynman.mf|, a library of \MF{} macros for drawing Feynman % diagrams in my thesis. The layout had to be chossen completely % manually, which required a long edit-process-preview cycle and made % |feynman.mf| awkward to use. % Nevertheless, it survived for five years without major % modifications, only slight enhancements had been made. Early in % 1994, I became aware of Thomas Leathrum's |mfpic|~\cite{mfpic}. % This inspired me to shift the user interface from \MF{} to % \LaTeX, because this allows a smoother blending of the \LaTeX{} % |picture| environment with \FMF{}. While doing this and after % having been taught by Tim Stelzer's and Bill Long's % \texttt{MADGRAPH}~\cite{madgraph} that minimizing the length of the % graph gives surprisingly good results for tree graphs\footnote{I had % thought about this earlier myself, but foolishly discarded the idea. % I didn't expect such a ``too simple'' method to give esthetically % pleasing results for loop graphs, which were my main concern.}, I % added the graph manipulation code in section~\ref{sec:graphs}. % And, of course, \FMF{} is biased towards those kinds of graphs that % my students, my colleagues and myself have to draw most often. % Comments for improvements from other areas of physics are welcome. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Projects} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsubsection{Documented \MF{} Interface} % In a future version, \FMF{} will have a more convenient and % supported set of macros at the \MF{} level, including more general % drawing primitives. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsubsection{Less Formal Graphs} % In addition to the well defined Feynman graphs of perturbation % theory there are also less formal and more illustrative graphs in % use. For example the ``quark diagrams'' familiar from papers on % hadronic weak decays involve curved lines illustrating the formation % of bound states, etc. Future versions of \FMF{} will provide better % support for such graphs, without the need for raw \MF{} coding. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsubsection{Virtual Graphs} % \label{sec:virtual-pictures} % In a future version, \FMF{} will be able to draw ``virtual'' % graphs, i.e.~graphs which are larger than the current limit enforced % by numeric overflow at higher resolutions. This can be implemented % by calculating the layout of a miniature graph and afterwards % distributing the full graph among several \MF{} characters. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Conclusion} % It goes without saying that \FMF{} is not perfect. There are % cases where using a graphical drawing tool with a mouse will give % more pleasing results in less time. But in most cases, \FMF{} % will give satisfactory results without any fine tuning. These will % be reproducible and independent from the computer it is running on. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \section{Usage} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Invocation} % Instructing \LaTeX{} to use \FMF{} is as simple as\footnote{As % given, this applies to \LaTeX. But the installation file % \texttt{feynmf209.ins} allows to generate special versions % \texttt{feynmf209.sty} and \texttt{feynmp209.sty} which are % compatible with the obsolete \LaTeX{} version 2.09. These files % are to be used as documentstyle options.} % \begin{verbatim} % \usepackage{feynmf} % \end{verbatim} % and calling \MF{} should not be harder as % \begin{verbatim} % mf '\mode:=localmode; input foobar' % \end{verbatim} % where |foobar| is the name of your \MF{} output file and |localmode| % is your local printer (e.g.~|laserjet|). % The hard part usually lies in instructing \TeX{} and your favorite % |dvi|-driver how to find the generated |tfm| and |gf| (resp.~|pk|) % files. This is highly system dependent and can be trivial (as in % the standard UNIX\footnote{UNIX was a trademark of UNIX Systems % Laboratory, but is rumored to have been donored to X/Open.} % \TeX{} installations) or almost impossible (as % under MVS). Please consult your local guide or local ``\TeX{} % Wizards'' on this point. % If you have \MP, then you can use it by placing % \begin{verbatim} % \usepackage[dvips]{feynmp} % \end{verbatim} % in your \LaTeX{} source. Here |dvips| is an option for the % \LaTeX{} |egraphics| package which is used for including the % generated PostScript files. It should be replaced by your local % supported |dvi| driver. Calling \MP{} is usually even simpler % \begin{verbatim} % mp foobar % \end{verbatim} % since there is no mode to be picked. % Please keep in mind that \FMF{} has been developed for \LaTeXe{} and % the \LaTeX~2.09 compatibility version will always be a retrofitted % hack. I will accept bug reports for the 2.09 version, but I urge % everybody to move to \LaTeX2e, which is the one and onloy supported % \LaTeX{} right now. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \begin{figure} % \begin{center} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \setlength{\unitlength}{0.012500in}% % \begingroup\makeatletter\ifx\SetFigFont\undefined % \def\x#1#2#3#4#5#6#7\relax{\def\x{#1#2#3#4#5#6}}% % \expandafter\x\fmtname xxxxxx\relax \def\y{splain}% % \ifx\x\y % LaTeX or SliTeX? % \gdef\SetFigFont#1#2#3{% % \ifnum #1<17\tiny\else \ifnum #1<20\small\else % \ifnum #1<24\normalsize\else \ifnum #1<29\large\else % \ifnum #1<34\Large\else \ifnum #1<41\LARGE\else % \huge\fi\fi\fi\fi\fi\fi % \csname #3\endcsname}% % \else % \gdef\SetFigFont#1#2#3{\begingroup % \count@#1\relax \ifnum 25<\count@\count@25\fi % \def\x{\endgroup\@setsize\SetFigFont{#2pt}}% % \expandafter\x % \csname \romannumeral\the\count@ pt\expandafter\endcsname % \csname @\romannumeral\the\count@ pt\endcsname % \csname #3\endcsname}% % \fi % \fi\endgroup % \begin{picture}(377,400)(3,420) % \thinlines % \put( 40,740){\framebox(80,80){}} % \put( 55,795){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}foo.tex}}} % \put(280,760){\framebox(60,40){}} % \put(295,780){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.mf}}} % \put(160,680){\framebox(60,40){}} % \put(170,705){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.log}}} % \put(320,640){\framebox(60,40){}} % \put(323,664){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.300gf}}} % \put(100,600){\framebox(60,40){}} % \put(110,620){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.t1}}} % \put(180,600){\framebox(60,40){}} % \put(185,622){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.t2}}} % \put(260,560){\framebox(60,40){}} % \put(270,585){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.tfm}}} % \put( 40,420){\framebox(80,80){}} % \put( 50,485){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}foo.dvi}}} % \put(290,463){\oval(130,74)} % \put(260,470){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}lpr}}} % \thicklines % \put(295,760){\vector(-3,-1){106.500}} % \put(325,760){\vector( 1,-3){ 26.500}} % \put(310,760){\vector(-1,-4){ 39.118}} % \multiput(120,780)(11.85185,0.00000){14}{\line( 1, 0){ 5.926}} % \put(280,780){\vector( 1, 0){0}} % \put( 60,500){\vector( 0,-1){0}} % \multiput( 60,740)(0.00000,-4.52830){53}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}} % \put( 80,500){\vector(-1,-2){0}} % \multiput(130,600)(-2.00000,-4.00000){25}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}} % \put(120,480){\vector(-2,-1){0}} % \multiput(280,560)(-4.00000,-2.00000){40}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}} % \put(210,640){\vector( 1,-4){0}} % \multiput(200,680)(1.11764,-4.47058){9}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}} % \put(129,642){\vector(-4,-3){0}} % \multiput(180,680)(-3.65714,-2.74286){14}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}} % \thinlines % \put(120,460){\vector( 1, 0){105}} % \put(300,560){\vector( 0,-1){ 60}} % \put(350,640){\vector( 0,-1){145}} % \thicklines % \put(105,494){\vector(-1,-1){0}} % \multiput(211,600)(-3.19697,-3.19697){33}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}} % \put(160,790){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{rm}\LaTeX{} \#1}}} % \put(360,535){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{rm}dvi2xxx}}} % \put(350,725){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{rm}\MF}}} % \put( 3,663){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{rm}\LaTeX{} \#2}}} % \end{picture} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \end{center} % \caption{Flow of information in a \FMF{} application: The % first \LaTeX{} pass is shown with a dashed line. The \MF{} % pass is shown with the full lines and the second \LaTeX{} pass % with dotted lines. The final dvi translation step is shown with % thin lines.} % \label{fig:flow} % \end{figure} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % The flow of information depicted in figure~\ref{fig:flow} looks much % more complicated than it is. The important feature is that there a % two sets of files which can be used to distribute a document: % \begin{enumerate} % \item{} Iff the recipient has a working \MF{} installation % (which shouldn't be a problem, except for some impoverished % commercial implementations), the document can be typset from the % \LaTeX{} source \emph{alone}, by running \LaTeX{}, \MF{} % and \LaTeX{} again (the latter step might have to be repeated to % get cross references right). % \item{} Another possibility (which doesn't require \MF{} on % the recipient's side), is to distribute the \LaTeX{} source, the % |tfm| and |gf| files (or |pk| files respectively) along with the % label files with extension |t|$n$ (where $n$ as an integer). % Distributing the \MF{} |log| files is a possible alternative % for the latter, but discouraged, because these are prone to be % erased accidentally. % \end{enumerate} % I should add one caveat here: some |dvi| file previewers % (e.g.~xdvi(1) under UNIX) do \emph{not} reread font information if % the |tfm| or |pk| files have changed, even though they reread the % |dvi| file if it has changed. Thus you have to restart such % previewers if you have made changes in diagrams to see these changes % on the screen. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \begin{figure} % \begin{center} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \setlength{\unitlength}{0.012500in}% % \begingroup\makeatletter\ifx\SetFigFont\undefined % \def\x#1#2#3#4#5#6#7\relax{\def\x{#1#2#3#4#5#6}}% % \expandafter\x\fmtname xxxxxx\relax \def\y{splain}% % \ifx\x\y % LaTeX or SliTeX? % \gdef\SetFigFont#1#2#3{% % \ifnum #1<17\tiny\else \ifnum #1<20\small\else % \ifnum #1<24\normalsize\else \ifnum #1<29\large\else % \ifnum #1<34\Large\else \ifnum #1<41\LARGE\else % \huge\fi\fi\fi\fi\fi\fi % \csname #3\endcsname}% % \else % \gdef\SetFigFont#1#2#3{\begingroup % \count@#1\relax \ifnum 25<\count@\count@25\fi % \def\x{\endgroup\@setsize\SetFigFont{#2pt}}% % \expandafter\x % \csname \romannumeral\the\count@ pt\expandafter\endcsname % \csname @\romannumeral\the\count@ pt\endcsname % \csname #3\endcsname}% % \fi % \fi\endgroup % \begin{picture}(357,400)(3,420) % \thinlines % \put( 40,740){\framebox(80,80){}} % \put( 55,795){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}foo.tex}}} % \put( 40,420){\framebox(80,80){}} % \put( 50,485){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}foo.dvi}}} % \put(290,463){\oval(130,74)} % \put(260,470){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}lpr}}} % \put(100,640){\framebox(60,40){}} % \put(110,660){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.t1}}} % \put(180,640){\framebox(60,40){}} % \put(185,662){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.t2}}} % \put(220,580){\framebox(60,40){}} % \put(230,605){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.1}}} % \put(300,580){\framebox(60,40){}} % \put(303,604){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.2}}} % \put(280,760){\framebox(60,40){}} % \put(295,780){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.mp}}} % \thicklines % \put(325,760){\vector( 0,-1){140}} % \put(310,760){\vector(-1,-2){ 69}} % \multiput(120,780)(11.85185,0.00000){14}{\line( 1, 0){ 5.926}} % \put(280,780){\vector( 1, 0){0}} % \put( 60,500){\vector( 0,-1){0}} % \multiput( 60,740)(0.00000,-4.52830){53}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}} % \put( 83,499){\vector(-1,-3){0}} % \multiput(130,640)(-1.42424,-4.27273){33}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}} % \put(115,486){\vector(-4,-3){0}} % \multiput(240,580)(-3.56571,-2.67429){35}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}} % \thinlines % \put(120,460){\vector( 1, 0){105}} % \put(260,580){\vector( 1,-2){ 40}} % \thicklines % \put(104,497){\vector(-3,-4){0}} % \multiput(211,640)(-2.67900,-3.57200){40}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}} % \thinlines % \put(345,580){\vector(-1,-2){ 40}} % \thicklines % \put(295,760){\vector(-1,-1){ 82}} % \put(295,760){\vector(-2,-1){164}} % \put(120,480){\vector(-2,-1){0}} % \multiput(320,580)(-4.00000,-2.00000){50}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}} % \put(160,790){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{rm}\LaTeX \#1}}} % \put( 3,663){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{rm}\LaTeX \#2}}} % \put(345,520){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{rm}dvips}}} % \put(340,685){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{rm}\MP}}} % \end{picture} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \end{center} % \caption{Flow of information in a \FMF{} application if \MP{} is % used instead of \MF.} % \label{fig:flowp} % \end{figure} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Basic usage} % The basic features of \FMF{} are (or rather ``should be'') % available through the \LaTeX{} interface. Not knowledge of % \MF{} is necessary. % \DescribeEnv{fmffile} % Upto 255 characters can be placed into one \MF{} file, they are % enclosed in a single |fmffile| environment. The environment % takes the filename as argument. Currently \FMF{} does \emph{not} % check that the 255 character limit per file is not overrun. % \begin{verbatim} % \begin{fmffile}{foobar} % ... % \end{fmffile} % \end{verbatim} % Note that the filename for the \MF{} file given in the argument of % the |fmffile| environment \emph{must not} be identical to the % \LaTeX{} source file name, because the \MF{} |.log| would be % overwritten and \LaTeX{} can no longer access the information in % this |.log| file. % \DescribeEnv{fmfchar} % Draw one character and place it here. Arguments are % |(|\meta{width}|,|\meta{height}|)| as in: % \begin{verbatim} % \begin{fmfchar}(40,25) % ... % \end{fmfchar} % \end{verbatim} % This environment does \emph{not} support labels, use |fmfchar*| if % your diagrams contains labels. % \DescribeEnv{fmfchar*} % Same as |fmfchar|, but enclosed in a |picture| environment of the % same size and supporting \LaTeX{} labels. % \begin{verbatim} % \begin{fmfchar*}(40,25) % ... % \end{fmfchar*} % \end{verbatim} % \DescribeMacro{\fmfleft} % \DescribeMacro{\fmfright} % \DescribeMacro{\fmfbottom} % \DescribeMacro{\fmftop} % \DescribeMacro{\fmfsurround} % Positioning of % external vertices has to done explicitely. The technical reason is % that they would otherwise collapse with their neighbors, but % practical reasons also suggest to give the user full control here. % |\fmfleft{|\meta{v1}$[$|,|\ldots$]$|}| places the % vertices in the comma separated list \meta{v1},\ldots % equidistantly on a smooth path on the left side of the diagram. % |\fmfright{|\meta{v1}$[$|,|\ldots$]$|}| does the same % thing on the right. Similarly |\fmfbottom| and |\fmftop|, while % |\fmfsurround{|\meta{v1}$[$|,|\ldots$]$|}| % places its arguments on smooth path % surrounding the diagram: % \def\gallerylabels{% % \fmfdotn{v}{4}% % \fmflabel{$v_1$}{v1}% % \fmflabel{$v_2$}{v2}% % \fmflabel{$v_3$}{v3}% % \fmflabel{$v_4$}{v4}} % \begin{center} % \label{p:galleries} % \hfil\\ % \fbox{\begin{fmfchar*}(15,12) % \fmfpen{thick}% % \fmfbottomn{v}{4}\gallerylabels % \fmfcmd{draw (bottom_gallery);} % \end{fmfchar*}}\qquad % \fbox{\begin{fmfchar*}(15,12) % \fmfpen{thick}% % \fmfleftn{v}{4}\gallerylabels % \fmfcmd{draw (left_gallery);} % \end{fmfchar*}}\qquad % \fbox{\begin{fmfchar*}(15,12) % \fmfpen{thick}% % \fmfsurroundn{v}{7}\fmfdotn{v}{7}% % \fmflabel{$v_1$}{v1}\fmflabel{$v_2$}{v2}% % \fmflabel{$v_3$}{v3}\fmflabel{$v_4$}{v4}% % \fmflabel{$v_5$}{v5}\fmflabel{$v_6$}{v6}% % \fmflabel{$v_7$}{v7}% % \fmfcmd{draw (surround_gallery);} % \end{fmfchar*}}\qquad % \fbox{\begin{fmfchar*}(15,12) % \fmfpen{thick}% % \fmftopn{v}{4}\gallerylabels % \fmfcmd{draw (top_gallery);} % \end{fmfchar*}}\qquad % \fbox{\begin{fmfchar*}(15,12) % \fmfpen{thick}% % \fmfrightn{v}{4}\gallerylabels % \fmfcmd{draw (right_gallery);} % \end{fmfchar*}}\\ % \hfil % \end{center} % \DescribeMacro{\fmfpen} % Pick up a pen of the specified size. |\fmfpen{|\meta{weight}|}| % is used for changing the weight (i.e.~thickness) of the lines. % Predefined sizes are |thin| and |thick|. % \def\linesample#1{% % \begin{fmfchar}(30,4) % \fmfleft{i1,i2} % \fmfright{o1,o2} % \fmf{#1}{i1,o1} % \end{fmfchar}} % \begin{table} % \begin{tabular}{lcll} % Name & Example & Parameters & Aliases \\\hline % |curly| & \linesample{curly} & |curly_len| & |gluon| \\ % |dbl_curly| & \linesample{dbl_curly} & |curly_len| & \\ % |dashes| & \linesample{dashes} & |dash_len| & \\ % |dashes_arrow| & \linesample{dashes_arrow} & |dash_len| & |scalar| \\ % |dbl_dashes| & \linesample{dbl_dashes} & |dash_len| & \\ % |dbl_dashes_arrow| & \linesample{dbl_dashes_arrow} & |dash_len| & \\ % |dots| & \linesample{dots} & |dot_len| & \\ % |dots_arrow| & \linesample{dots_arrow} & |dot_len| & |ghost| \\ % |dbl_dots| & \linesample{dbl_dots} & |dot_len| & \\ % |dbl_dots_arrow| & \linesample{dbl_dots_arrow} & |dot_len| & \\ % |phantom| & \linesample{phantom} & & \\ % |phantom_arrow| & \linesample{phantom_arrow} & & \\ % |plain| & \linesample{plain} & & |vanilla|\\ % |plain_arrow| & \linesample{plain_arrow} & & |fermion|, % |electron|, % |quark| \\ % |dbl_plain| & \linesample{dbl_plain} & & |double| \\ % |dbl_plain_arrow| & \linesample{dbl_plain_arrow} & & |double_arrow|, % |heavy| \\ % |wiggly| & \linesample{wiggly} & |wiggly_len|& |boson|, % |photon| \\ % |dbl_wiggly| & \linesample{dbl_wiggly} & |wiggly_len|& % \end{tabular} % \caption{Available line styles} % \label{tab:line-styles} % \end{table} % \begin{table} % \begin{tabular}{lp{60mm}} % Name & Explanation \\\hline % |tension| & draw a tighter ($>1$) or more loos ($<1$) arc \\ % |left| & draw on a halfcircle on the left \\ % |right| & draw on a halfcircle on the right \\ % |straight| & draw on a straight line \\ % |label| & \TeX{} text for labeling the arc \\ % |label.side| & force placement of the label on the |left| or % |right| \\ % |label.dist| & place label at a distance |dist| \\ % |label.pos| & relative position of the label % (not implemented yet!) \\ % |decoration.shape| & shape of decoration % (not implemented yet!) \\ % |decoration.size| & size of decoration % (not implemented yet!) \\ % |decoration.pos| & relative position of decoration % (not implemented yet!) \\ % |decoration.filled| & fill, shade or hatch decoration % (not implemented yet!) \\ % |decoration.angle| & rotate decoration relative to default % (not implemented yet!) % \end{tabular} % \caption{Available line options} % \label{tab:line-options} % \end{table} % \DescribeMacro{\fmf} % This is the the most frequently used macro in \FMF{} applications. % |\fmf{|\meta{style}\allowbreak % $[$|,|\meta{opt}\allowbreak % $[$|=|\meta{val}$]$|,|\ldots$]$|}{|\meta{v1}|,|\meta{v2}\allowbreak % $[$|,|\ldots$]$|}| % connects the vertices \textit{v1,v2,\ldots} with a line of style % \meta{style}, using a set of options \meta{opt} with (optional) % value \meta{val}. If a vertex is not % known yet, it is added to the diagram. Note that the actual drawing % is not done immediately, because the positions can only be % calculated when \emph{all} vertices are known. The currently % available styles are collected in table~\ref{tab:line-styles}. Most % names should be self explanatory % and are not discussed further. % The |dashes|, |dots|, |phantom| and |plain| styles can optionally be % decorated with an arrow as shown above. All styles, including % |curly| and |wiggly|, can be doubled. But arrows are not available % for the latter two, because esthetically pleasing results can not be % expected. The |phantom| % style is special, because it % only enters the vertices and does \emph{not} cause a line to be % drawn. This is extremely useful for advanced layout features, as % explained below. % The supported options are collected in % table~\ref{tab:line-options}\footnote{% % \begin{dubious} % One particulary useful further option would be \texttt{smooth}, % allowing for several lines joined smoothly. Early % experimentation has shown however, that the results are not % always what one expects and that there is a lot of room for % abuse. % \end{dubious}}. % Note that each of the dot separated components of the options can be % abbreviated. For example, |l.d| is equivalent to |label.dist|. The % result of ambiguous matches is however undefined. % \begin{table} % \begin{tabular}{lp{60mm}} % Name & Explanation \\\hline % |label| & \TeX{} text for labeling the vertex \\ % |label.angle| & force placement of the label at the given % angle from the vertex \\ % |label.dist| & place label at a distance |dist| \\ % |decoration.shape| & shape of decoration \\ % |decoration.size| & size of decoration \\ % |decoration.filled| & fill, shade or hatch decoration \\ % |decoration.angle| & rotate decoration % \end{tabular} % \caption{Available vertex options} % \label{tab:vertex-options} % \end{table} % \DescribeMacro{\fmfv} % Declare vertices with options: % |\fmfv{|\meta{shape}$[$|=|\meta{val}$]$\allowbreak % $[$|,|\meta{opt}\allowbreak % $[$|=|\meta{val}$]$|,|\ldots$]$|}{|\meta{v1}\allowbreak % $[$|,|\ldots$]$|}| % This is used for adding labels to a vertex and for specifying other % decoration. Supported options are collected in % table~\ref{tab:vertex-options}. Here the same abbreviation % mechanism as above is in effect. The available |shape|s are listed % in various filling styles in table~\ref{tab:vertex-shapes}\footnote{% % If the variable \texttt{feymfwizard} is \texttt{true} (e.g.~after % calling the \texttt{fmfwizard} macro), % it is also possible to specify any \MF{} expression that evaluates % to a \texttt{path}. Naturally, this has to used with great care, % because strange errors can be triggered by typos!}. % \def\VertexSample#1#2{% % \begin{fmfchar}(8,8) % \fmfforce{(.5w,.4h)}{c} % \fmfv{d.shape=#1,d.filled=#2}{c} % \end{fmfchar}} % \def\VertexSamples#1{% % \VertexSample{#1}{-.5} & \VertexSample{#1}{0} % & \VertexSample{#1}{.5} & \VertexSample{#1}{1}} % \begin{table} % \begin{center} % \begin{tabular}{lcccc} % & |filled=-.5| & |filled=0| & |filled=.5| & |filled=1| \\ % \hline % |circle| & \VertexSamples{circle} \\ % |square| & \VertexSamples{square} \\ % |triangle| & \VertexSamples{triangle} \\ % |diamond| & \VertexSamples{diamond} \\ % |pentagon| & \VertexSamples{pentagon} \\ % |hexagon| & \VertexSamples{hexagon} \\ % |triagram| & \VertexSamples{triagram} \\ % |tetragram|& \VertexSamples{tetragram} \\ % |pentagram|& \VertexSamples{pentagram} \\ % |hexagram| & \VertexSamples{hexagram} % \end{tabular} % \end{center} % \caption{Available vertex shapes and fill styles.} % \label{tab:vertex-shapes} % \end{table} % \DescribeMacro{\fmfblob} % Draw a blob of the specified diameter at the vertices. % |\fmfblob{|\meta{diameter}|}{|\meta{v1}\allowbreak % $[$|,|\ldots$]$|}| is equivalent to % |\fmfv{decor.shape=circle,|\allowbreak|decor.filled=.5,|\allowbreak % |decor.size=|\meta{diameter}\allowbreak % |}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}| % \DescribeMacro{\fmfdot} % Draw a dot at the vertices given as arguments. % |\fmfdot{|\meta{v1}\allowbreak % $[$|,|\ldots$]$|}| is equivalent to % |\fmfv{decor.shape=circle,|\allowbreak|decor.filled=1,|\allowbreak % |decor.size=2thick|\allowbreak % |}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}| % \DescribeMacro{\fmfposition} % Calculate the positions of the vertices based on the arcs which are % defined up to this point. Usually this calculation is performed % automatically at the end of the |fmfchar| environment. Calling it % explicitely, is useful for adding arcs which should not enter the % calculation. % \DescribeMacro{\fmfforce} % |\fmfforce{|\meta{pos}|}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}| % forces the position \meta{pos} of the vertices \meta{v1}\ldots, % bypassing the automatic layout. % \DescribeMacro{\fmfshift} % |\fmfforce{|\meta{dist}|}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}| % shifts the position of the vertices \meta{v1}\ldots{} by \meta{dist} % from the automatic layout. % \DescribeMacro{\fmffixed} % |\fmfforce{|\meta{dist}|}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}| % fixes the distance between subsequent vertices in the list % \meta{v1}\ldots{} to \meta{dist}. % This command should be used with care, because it is possible to % overconstrain the layout of the graph and the error messages will be % obscure to a novice user. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Examples} % As an example, consider drawing a straightforward box diagram, % familier from $K$-$\bar K$, $D$-$\bar D$, and $B$-$\bar B$ mixing. % The commands for the labels are not shown here, they are discussed % in section~\ref{sec:labels} % \vspace*{\baselineskip} % \begin{minipage}{0.6\linewidth} % We start the diagram and pick up a thick pen: % \begin{verbatim} % \begin{fmfchar}(40,25) % \fmfpen{thick} % \end{verbatim} % The incoming and outcoming vertices are placed on the left and % right hand side, respectively: % \begin{verbatim} % \fmfleft{i1,i2} % \fmfright{o1,o2} % \end{verbatim} % Now we tell \FMF{} how the arcs are connected. % \begin{verbatim} % \fmf{fermion}{i1,v1,v3,o1} % \fmf{fermion}{o2,v4,v2,i2} % \fmf{photon}{v1,v2} % \fmf{photon}{v3,v4} % \end{verbatim} % Finally we tell \FMF{} to draw dots at the vertices and we're % done. % \begin{verbatim} % \fmfdot{v1,v2,v3,v4} % \end{fmfchar} % \end{verbatim} % \end{minipage} % \hfill % \begin{minipage}{0.35\linewidth} % \begin{center} % \begin{fmfchar*}(40,25) % \fmfpen{thick} % \fmfleft{i1,i2} % \fmflabel{$\noexpand\bar b$}{i1} % \fmflabel{$d$}{i2} % \fmfright{o1,o2} % \fmflabel{$\noexpand\bar d$}{o1} % \fmflabel{$b$}{o2} % \fmf{fermion}{i1,v1} % \fmf{fermion,label=$\noexpand\bar t,,\noexpand\bar c,, % \noexpand\bar u$,l.side=right}{v1,v3} % \fmf{fermion}{v3,o1} % \fmf{fermion}{o2,v4} % \fmf{fermion,label=$t,,c,,u$,l.side=right}{v4,v2} % \fmf{fermion}{v2,i2} % \fmf{photon,label=$W^+$,l.side=left}{v1,v2} % \fmf{photon,label=$W^-$,l.side=right}{v3,v4} % \fmfdot{v1,v2,v3,v4} % \end{fmfchar*} % \end{center} % \end{minipage} % \label{page:simple-examples} % Here is the resonant $s$-channel contribution to $e^+e^-\to 4f$. % (From now on, we do no longer display the % |\begin{fmfchar}(40,25)|, |\fmfpen{thick}|, \ldots, % |\end{fmfchar}| surrounding all pictures.) % \vspace*{\baselineskip} % \begin{minipage}{0.6\linewidth} % \begin{verbatim} % \fmfleft{i1,i2} % \fmfright{o1,o2,o3,o4} % \fmf{fermion}{i1,v1,i2} % \fmf{photon}{v1,v2} % \fmfblob{.15w}{v2} % \fmf{photon}{v2,v3} % \fmf{fermion}{o1,v3,o2} % \fmf{photon}{v2,v4} % \fmf{fermion}{o4,v4,o3} % \end{verbatim} % \end{minipage} % \hfill % \begin{minipage}{0.38\linewidth} % \begin{center} % \fmfframe(0,5)(5,7){% % \begin{fmfchar*}(40,25) % \fmfpen{thick} % \fmfleft{i1,i2} % \fmfright{o1,o2,o3,o4} % \fmflabel{$e_-$}{i1} % \fmflabel{$e_+$}{i2} % \fmf{fermion}{i1,v1,i2} % \fmf{photon}{v1,v2} % \fmfblob{.15w}{v2} % \fmf{photon}{v2,v3} % \fmflabel{$\noexpand\mu_+$}{o1} % \fmflabel{$\noexpand\nu_{\noexpand\mu}$}{o2} % \fmf{fermion}{o1,v3,o2} % \fmf{photon}{v2,v4} % \fmflabel{$\noexpand\bar c$}{o4} % \fmflabel{$s$}{o3} % \fmf{fermion}{o4,v4,o3} % \end{fmfchar*}} % \end{center} % \end{minipage} % And the resonant $t$-channel contribution: % \vspace*{\baselineskip} % \begin{minipage}{0.6\linewidth} % \begin{verbatim} % \fmfleft{i1,i2} % \fmfright{o1,o2,o3,o4} % \fmf{fermion}{i1,v1,v2,i2} % \fmf{photon}{v1,v3} % \fmf{fermion}{o1,v3,o2} % \fmf{photon}{v2,v4} % \fmf{fermion}{o4,v4,o3} % \end{verbatim} % \end{minipage} % \hfill % \begin{minipage}{0.38\linewidth} % \begin{center} % \fmfframe(0,5)(5,7){% % \begin{fmfchar*}(40,25) % \fmfpen{thick} % \fmfleft{i1,i2} % \fmfright{o1,o2,o3,o4} % \fmflabel{$e_-$}{i1} % \fmflabel{$e_+$}{i2} % \fmf{fermion}{i1,v1,v2,i2} % \fmf{photon}{v1,v3} % \fmflabel{$\noexpand\mu_+$}{o1} % \fmflabel{$\noexpand\nu_{\noexpand\mu}$}{o2} % \fmf{fermion}{o1,v3,o2} % \fmf{photon}{v2,v4} % \fmflabel{$\noexpand\bar c$}{o4} % \fmflabel{$s$}{o3} % \fmf{fermion}{o4,v4,o3} % \end{fmfchar*}} % \end{center} % \end{minipage} % Actually, these three diagrams can be improved slightly by using % |phantom| arcs, which will be discussed in the next section. % Two point loop diagrams pose another set of problems. We % must have a way of specifying that one or more of the lines % connecting the two vertices are \emph{not} connected by a straight % line. The options |left|, |right| and |straight| offer the % possibility to connect two vertices by a semicircle detour, either % on the left or on the right. Since by default all lines contribute % to the tension between two vertices, the |tension| option allows us % to reduce this tension. The next examples shows both options in % action. The lower fermion line is given an tension of~$1/3$ to % make is symmetrical with the upper line with consists of three parts. % The loop photon is using a detour on the right and does not % contribute any tension. % \vspace*{\baselineskip} % \begin{minipage}{0.6\linewidth} % \begin{verbatim} % \fmfleft{i1,i2} % \fmfright{o1} % \fmf{fermion,tension=1/3}{i1,v1} % \fmf{plain}{v1,v2} % \fmf{fermion}{v2,v3} % \fmf{photon,right,tension=0}{v2,v3} % \fmf{plain}{v3,i2} % \fmf{photon}{v1,o1} % \end{verbatim} % \end{minipage} % \hfill % \begin{minipage}{0.35\linewidth} % \begin{center} % \begin{fmfchar*}(40,25) % \fmfpen{thick} % \fmfleft{i1,i2} % \fmflabel{$p^{\noexpand\prime}$}{i1} % \fmflabel{$p$}{i2} % \fmfright{o1} % \fmflabel{$p+p^{\noexpand\prime}$}{o1} % \fmf{fermion,tension=1/3}{i1,v1} % \fmf{plain}{v1,v2} % \fmf{fermion,label=$p-k$,l.side=left}{v2,v3} % \fmf{photon,right,tension=0,label=$k$}{v2,v3} % \fmf{plain}{v3,i2} % \fmf{photon}{v1,o1} % \end{fmfchar*} % \end{center} % \end{minipage} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Labels} % \label{sec:labels} % Let us now come back to the examples on % page~\pageref{page:simple-examples} and discuss how to add the % labels. % \DescribeMacro{\fmflabel} % The macro |\fmflabel{|\meta{label}|}{|\meta{v}|}| adds the label % \meta{label} to the vertex \meta{v}. In the current implementation, % there can be only a single label for each vertex. Thus earlier % calls to |\fmflabel| for the same vertex will be overwritten. % \meta{label} will be placed with the |\put| command of the \LaTeX{} % |picture| environment. \emph{It is absolutely necessary to quote % \emph{each} \TeX{} control sequence appearing in \meta{label} with} % |\noexpand|. \emph{Otherwise all kinds of disasters are bound to % happen, causing at the very least some obscure error messages!} % Note that the |fmfchar*| environment must be used to use labels, % they will silently disappear in |fmfchar|. % |\fmflabel| gives the user \emph{no} control on the placement of % the the label (see below for a more fine-grained control provided by % the options to the |\fmfv| macro). The label is placed using the % following algorithm: % \begin{enumerate} % \item{} The reference point of the box containing \meta{label} is % placed at the distance |3thick| on the continuation of the % straight line connecting the center of the picture with the % vertex \meta{v}. % \item{} The reference point of the box is chosen such that the % contents of the box is on the outside of the vertex (with % respect to the center of the diagram). It is chosen from the % four corners and the four midpoints of the sides. % \end{enumerate} % Therefore the four external particles in the~$B$-$\bar B$ mixing % diagram on page~\pageref{page:simple-examples} are labelled simply % by: % \begin{verbatim} % \fmflabel{$\noexpand\bar b$}{i1} % \fmflabel{$d$}{i2} % \fmflabel{$\noexpand\bar d$}{o1} % \fmflabel{$b$}{o2} % \end{verbatim} % \begin{dubious} % Explain more of the |label| option and the default placement rules. % \end{dubious} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Advanced usage} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsubsection{Shrinking} % \DescribeEnv{fmfshrink} % Shrink the lineswidths and similar parameters in the enclosed section. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsubsection{Multiple vertices and arcs} % \DescribeMacro{\fmfleftn} % \DescribeMacro{\fmfrightn} % \DescribeMacro{\fmfbottomn} % \DescribeMacro{\fmftopn} % \DescribeMacro{\fmfsurroundn} % The macro is|\fmfleftn| is similar to |\fmfleft|, but % |\fmfleftn{|\meta{v}\allowbreak|}{|\meta{n}|}| places the % vertices % \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}. Analogously for % the macros |\fmfrightn|, |\fmfbottomn|, |\fmftopn| and % |\fmfsurroundn|. % \DescribeMacro{\fmfvn} % The macro |\fmfvn| is similar to |\fmfv|, but % |\fmfvn{|\meta{vertex}\allowbreak|}{|\meta{v}\allowbreak|}{|\meta{n}|}| % places the vertices \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}. % \DescribeMacro{\fmfdotn} % \DescribeMacro{\fmfblobn} % The macros |\fmfdotn| and |\fmfblobn| are similar to the |\fmfdot| % and |\fmfblob|, but |\fmfdotn{|\meta{v}|}{|\meta{n}|}| places the % vertices \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}. Analogously for % |\fmfblobn|. % \DescribeEnv{fmffor} % The environment |\begin{fmffor}{|\meta{var}\allowbreak % |}{|\meta{from}\allowbreak|}{|\meta{step}\allowbreak % |}{|\meta{to}\allowbreak|}|\allowbreak\meta{body}\allowbreak % |\end{fmffor}| % executes \meta{body} multiple times, setting \meta{var} to % $\meta{from}, \meta{from}+\meta{step}, \ldots, \meta{to}$. % \DescribeMacro{\fmfcyclen} % \DescribeMacro{\fmfrcyclen} % The macro |\fmfcyclen{|\meta{style}|}{|\meta{v}|}{|\meta{n}|}| % cyclically connects the vertices % \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}. |\fmfcyclen| operates in % reverse order. % An advanced application of the above \FMF{} features is shown in % figure~\ref{fig:euler-heisenberg}, which is generated by calling % the \TeX{} macro % \begin{verbatim} % \def\EulerHeisenberg#1{% % \begin{fmfchar}(40,25) % \fmfpen{thick} % \fmfsurroundn{e}{#1} % \begin{fmffor}{n}{1}{1}{#1} % \fmf{photon}{e[n],i[n]} % \end{fmffor} % \fmfcyclen{fermion,tension=#1/8}{i}{#1} % \end{fmfchar}} % \end{verbatim} % with the arguments 4, 6, 8, and 10, respectively. % \def\EulerHeisenberg#1{% % \begin{fmfchar}(40,25) % \fmfpen{thick} % \fmfsurroundn{e}{#1} % \begin{fmffor}{n}{1}{1}{#1} % \fmf{photon}{e[n],i[n]} % \end{fmffor} % \fmfcyclen{fermion,tension=#1/8}{i}{#1} % \end{fmfchar}} % \begin{figure} % \begin{center} % \EulerHeisenberg{4} \qquad \EulerHeisenberg{6} % \end{center} % \begin{center} % \EulerHeisenberg{8} \qquad \EulerHeisenberg{10} % \end{center} % \caption{Higher order terms in the Euler-Heisenberg lagrangian.} % \label{fig:euler-heisenberg} % \end{figure} % Similarly, we can draw the diagrams in figures~\ref{fig:PP-rings} % and~\ref{fig:PP-rings} from many particle physics: % \begin{verbatim} % \def\PPRing#1{% % \begin{fmfchar}(20,20) % \fmfsurroundn{v}{#1} % \fmfdotn{v}{#1} % \fmfcyclen{fermion,right=0.25}{v}{#1} % \fmfcyclen{fermion,left=0.25}{v}{#1} % \end{fmfchar}} % \def\PHRing#1{% % \begin{fmfchar}(20,20) % \fmfsurroundn{v}{#1} % \fmfdotn{v}{#1} % \fmfcyclen{fermion,right=0.25}{v}{#1} % \fmfrcyclen{fermion,right=0.25}{v}{#1} % \end{fmfchar}} % \end{verbatim} % \def\PPRing#1{% % \begin{fmfchar}(20,20) % \fmfsurroundn{v}{#1} % \fmfdotn{v}{#1} % \fmfcyclen{fermion,right=0.25}{v}{#1} % \fmfcyclen{fermion,left=0.25}{v}{#1} % \end{fmfchar}} % \def\PHRing#1{% % \begin{fmfchar}(20,20) % \fmfsurroundn{v}{#1} % \fmfdotn{v}{#1} % \fmfcyclen{fermion,right=0.25}{v}{#1} % \fmfrcyclen{fermion,right=0.25}{v}{#1} % \end{fmfchar}} % \begin{figure} % \begin{center} % \PPRing{3}\qquad\PPRing{4}\qquad\PPRing{5}\qquad\PPRing{6} % \end{center} % \caption{Particle-particle ring diagrams} % \label{fig:PP-rings} % \end{figure} % \begin{figure} % \begin{center} % \PHRing{3}\qquad\PHRing{4}\qquad\PHRing{5}\qquad\PHRing{6} % \end{center} % \caption{Particle-hole ring diagrams} % \label{fig:PH-rings} % \end{figure} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsubsection{Tight arcs} % If you add to any arc one or more |phantom| arcs they will cause % a tighter bonding between the vertices involved % \begin{verbatim} % \fmf{fermion}{v1,v2} % \fmf{phantom}{v1,v2} % \end{verbatim} % which is equivalent to % \begin{verbatim} % \fmf{fermion,tension=2}{v1,v2} % \end{verbatim} % The |phantom| arc has to be added \emph{before} any |\fmfposition| % involving these vertices, of course. Here is an example from deep % inelastic scattering. (We do not show the |\fmfcmd{}|s in this % example which are used for decorating the incoming proton and do not % affect \FMF's layout decisions.) % \vspace*{\baselineskip} % \begin{minipage}{0.6\linewidth} % \begin{verbatim} % \fmfleft{ip,il} % \fmfright{oq1,oq2,d1,oq3,d2,d3,ol} % \fmf{fermion}{ip,vp,vq,oq3} % \fmf{fermion}{vp,oq1} % \fmf{fermion}{vp,oq2} % \fmf{photon}{vl,vq} % \fmf{fermion}{il,vl,ol} % \fmfblob{.15w}{vp} % \fmfdot{vq} % \end{verbatim} % \end{minipage} % \hfill % \begin{minipage}{0.35\linewidth} % \begin{center} % \begin{fmfchar}(40,25) % \fmfpen{thick} % \fmfleft{ip,il} % \fmfright{oq1,oq2,d1,oq3,d2,d3,ol} % \fmf{fermion}{ip,vp,vq,oq3} % \fmf{fermion}{vp,oq1} % \fmf{fermion}{vp,oq2} % \fmf{photon}{vl,vq} % \fmf{fermion}{il,vl,ol} % \fmfposition % \fmfforce{vloc ip+(0,2thick)}{ipp} % \fmfforce{vloc ip-(0,2thick)}{ipm} % \fmfforce{vloc vp+(0,2thick)}{vpp} % \fmfforce{vloc vp-(0,2thick)}{vpm} % \fmfshift{0.12 (vloc ip - vloc vp)}{vpp} % \fmfshift{0.10 (vloc ip - vloc vp)}{vpm} % \fmf{plain}{ipp,vpp} % \fmf{plain}{ipm,vpm} % \fmfblob{.15w}{vp} % \fmfdot{vq} % \end{fmfchar} % \end{center} % \end{minipage} % As it stands, all vertices come out too far to the right, because % the greater number of outgoing lines pulls them over. Adding % |\fmf{phantom}| makes the bond between the incoming vertices and the % interactions tighter and produces a better balanced picture: % \vspace*{\baselineskip} % \begin{minipage}{0.6\linewidth} % \begin{verbatim} % \fmfleft{ip,il} % \fmfright{oq1,oq2,d1,oq3,d2,d3,ol} % \fmf{fermion}{ip,vp,vq,oq3} % \fmf{phantom}{ip,vp} % \fmf{fermion}{vp,oq1} % \fmf{fermion}{vp,oq2} % \fmf{photon}{vl,vq} % \fmf{fermion}{il,vl,ol} % \fmf{phantom}{il,vl} % \fmfblob{.15w}{vp} % \fmfdot{vq} % \end{verbatim} % \end{minipage} % \hfill % \begin{minipage}{0.35\linewidth} % \begin{center} % \begin{fmfchar}(40,25) % \fmfpen{thick} % \fmfleft{ip,il} % \fmfright{oq1,oq2,d1,oq3,d2,d3,ol} % \fmf{fermion}{ip,vp,vq,oq3} % \fmf{phantom}{ip,vp} % \fmf{fermion}{vp,oq1} % \fmf{fermion}{vp,oq2} % \fmf{photon}{vl,vq} % \fmf{fermion}{il,vl,ol} % \fmf{phantom}{il,vl} % \fmfposition % \fmfforce{vloc ip+(0,2thick)}{ipp} % \fmfforce{vloc ip-(0,2thick)}{ipm} % \fmfforce{vloc vp+(0,2thick)}{vpp} % \fmfforce{vloc vp-(0,2thick)}{vpm} % \fmfshift{0.16 (vloc ip - vloc vp)}{vpp} % \fmfshift{0.14 (vloc ip - vloc vp)}{vpm} % \fmf{plain}{ipp,vpp} % \fmf{plain}{ipm,vpm} % \fmfblob{.15w}{vp} % \fmfdot{vq} % \end{fmfchar} % \end{center} % \end{minipage} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsubsection{Loose arcs} % Adding arcs \emph{after} any |\fmfposition| involving these % vertices will make these arcs loose, i.e.~they will not contribute % to the bonding between the vertices. % Consider the following example: suppose we want to draw a ladder % diagram contributing to the quark form factor. Simply linking in % the gluons does not produce a satisfactory result: % \vspace*{\baselineskip} % \begin{minipage}{0.6\linewidth} % \begin{verbatim} % \fmfleft{i1} \fmfright{o1,o2} % \fmf{photon}{i1,v4} % \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2} % \fmf{gluon}{v1,v7} % \fmf{gluon}{v2,v6} % \fmf{gluon}{v3,v5} % \end{verbatim} % \end{minipage} % \hfill % \begin{minipage}{0.35\linewidth} % \begin{center} % \begin{fmfchar}(40,25) % \fmfpen{thick} % \fmfleft{i1} \fmfright{o1,o2} % \fmf{photon}{v4,i1} % \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2} % \fmf{gluon}{v1,v7} % \fmf{gluon}{v2,v6} % \fmf{gluon}{v3,v5} % \end{fmfchar} % \end{center} % \end{minipage} % What went wrong? Obviously the gluons are bonding the quark lines % too strongly. The fix is simple: just exclude the gluons from the % calculation and add them later as infinitely stretchable: % \vspace*{\baselineskip} % \begin{minipage}{0.6\linewidth} % \begin{verbatim} % \fmfleft{i1} \fmfright{o1,o2} % \fmf{photon}{i1,v4} % \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2} % \fmfposition % \fmf{gluon}{v1,v7} % \fmf{gluon}{v2,v6} % \fmf{gluon}{v3,v5} % \end{verbatim} % \end{minipage} % \hfill % \begin{minipage}{0.35\linewidth} % \begin{center} % \begin{fmfchar}(40,25) % \fmfpen{thick} % \fmfleft{i1} \fmfright{o1,o2} % \fmf{photon}{v4,i1} % \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2} % \fmfposition % \fmf{gluon}{v1,v7} % \fmf{gluon}{v2,v6} % \fmf{gluon}{v3,v5} % \end{fmfchar} % \end{center} % \end{minipage} % Another instructive example is the following: imagine you want to % draw a typical non-resonant contribution to~$e^+e^-\to 4f$. The % obvious solution doesn's look right. % \vspace*{\baselineskip} % \begin{minipage}{0.6\linewidth} % \begin{verbatim} % \fmfleft{i1,i2} % \fmfright{o1,o2,o3,o4} % \fmf{fermion}{i1,v1,i2} % \fmf{photon}{v1,v2} % \fmf{fermion}{o1,v2,v3,o4} % \fmf{photon}{v3,v4} % \fmf{fermion}{o3,v4,o2} % \end{verbatim} % \end{minipage} % \hfill % \begin{minipage}{0.35\linewidth} % \begin{center} % \begin{fmfchar}(40,25) % \fmfpen{thick} % \fmfleft{i1,i2} % \fmfright{o1,o2,o3,o4} % \fmf{fermion}{i1,v1,i2} % \fmf{photon}{v1,v2} % \fmf{fermion}{o1,v2,v3,o4} % \fmf{photon}{v3,v4} % \fmf{fermion}{o3,v4,o2} % \end{fmfchar} % \end{center} % \end{minipage} % One way to fix it is to |\fmfshift| the three rightmost vertices by % hand: % \vspace*{\baselineskip} % \begin{minipage}{0.6\linewidth} % \begin{verbatim} % \fmfleft{i1,i2} % \fmfright{o1,o2,o3,o4} % \fmf{fermion}{i1,v1,i2} % \fmf{photon}{v1,v2} % \fmf{fermion}{o1,v2,v3,o4} % \fmf{photon}{v3,v4} % \fmf{fermion}{o3,v4,o2} % \fmfposition % \fmfshift{-.1w,0}{v2,v3,v4} % \end{verbatim} % \end{minipage} % \hfill % \begin{minipage}{0.35\linewidth} % \begin{center} % \begin{fmfchar}(40,25) % \fmfpen{thick} % \fmfleft{i1,i2} % \fmfright{o1,o2,o3,o4} % \fmf{fermion}{i1,v1,i2} % \fmf{photon}{v1,v2} % \fmf{fermion}{o1,v2,v3,o4} % \fmf{photon}{v3,v4} % \fmf{fermion}{o3,v4,o2} % \fmfposition % \fmfshift{-.1w,0}{v2,v3,v4} % \end{fmfchar} % \end{center} % \end{minipage} % A smarter solution is again to make certain arcs stretchable: % \vspace*{\baselineskip} % \begin{minipage}{0.6\linewidth} % \begin{verbatim} % \fmfleft{i1,i2} % \fmfright{o1,o2,o3,o4} % \fmf{fermion}{i1,v1,i2} % \fmf{photon}{v1,v2} % \fmf{fermion}{o1,v2,v3,o4} % \fmfposition % \fmf{photon}{v3,v4} % \fmf{fermion}{o3,v4,o2} % \end{verbatim} % \end{minipage} % \hfill % \begin{minipage}{0.35\linewidth} % \begin{center} % \begin{fmfchar}(40,25) % \fmfpen{thick} % \fmfleft{i1,i2} % \fmfright{o1,o2,o3,o4} % \fmf{fermion}{i1,v1,i2} % \fmf{photon}{v1,v2} % \fmf{fermion}{o1,v2,v3,o4} % \fmfposition % \fmf{photon}{v3,v4} % \fmf{fermion}{o3,v4,o2} % \end{fmfchar} % \end{center} % \end{minipage} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsubsection{Avoiding continuously tight and loose arcs} % I have been very reluctant to implement continuously tight and loose % arcs in \FMF, because it introduces to much opportunity for % ``fiddling'' on the user's part. However, since the present % implementation blends rather nicely with the options syntax, I have % decided to add it anyway. I hope that most diagrams will be created % without too much ``fiddling''. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsubsection{Raw \MF} % Some more advanced features of \FMF{} are more conveniently % accessed through raw \MF{} commands. This can either be % achieved by preparing a \MF{} input file or by using |\fmfcmd| % extensively. The latter apprach is usally more convenient. % \DescribeMacro{\fmfcmd} % The |\fmfcmd| macro writes its argument into the \MF{} input % file generated by \FMF. While some experience in using % \MF{} doesn't hurt here, this approach can simplify the % production of complex diagrams considerably. % Here's an interesting ``abuse'' of \FMF. Using the undocumented % \MF{} macros (like |vdraw_vertex_label|) is possible, though not % supported. In a future versions, these features will be made % available through supported interfaces. % \begin{minipage}{0.6\linewidth} % \begin{verbatim} % \begin{fmfchar*}(40,40)\fmfcmd{ % pair o,xm,xp,ym,yp; % pair v.loc; string v.lbl; % o:=(.5w,.1h); % xm:=(0,.1h); xp:=(w,.1h); % ym:=(.5w,0); yp:=(.5w,h); % v.loc := xp; v.lbl := "$x$"; % v.lbl.ang := -135; v.lbl.dist := 2; % vdraw_vertex_label v; % v.loc := yp; v.lbl := "$y=x^2$"; % vdraw_vertex_label v; % pickup pencircle scaled thin; % draw xm--xp; draw ym--yp; % pickup pencircle scaled thick; % xs:=xpart(xp-o); ys:=ypart(yp-o); % draw (o + (-xs,ys)) for n = -9 upto 10: % --(o + (xs*(n/10),ys*((n/10)**2))) % endfor;} % \end{fmfchar*} % \end{verbatim} % \end{minipage} % \hfill % \begin{minipage}{0.35\linewidth} % \begin{center} % \begin{fmfchar*}(40,40)\fmfcmd{ % pair o,xm,xp,ym,yp; % pair v.loc; string v.lbl; % o:=(.5w,.1h); % xm:=(0,.1h); xp:=(w,.1h); % ym:=(.5w,0); yp:=(.5w,h); % v.loc := xp; v.lbl := "$x$"; % v.lbl.ang := -135; v.lbl.dist := 2; % vdraw_vertex_label v; % v.loc := yp; v.lbl := "$y=x^2$"; % vdraw_vertex_label v; % pickup pencircle scaled thin; % draw xm--xp; draw ym--yp; % pickup pencircle scaled thick; % xs:=xpart(xp-o); ys:=ypart(yp-o); % draw (o + (-xs,ys)) for n = -9 upto 10: % --(o + (xs*(n/10),ys*((n/10)**2))) % endfor;} % \end{fmfchar*} % \end{center} % \end{minipage} % Finally, for the curious, here is how to draw the circular gluons in % figure~\ref{fig:gluons}: % \begin{verbatim} % \fmfcmd{draw_gluon (fullcircle scaled .5w shifted (.5w,.5h));} % \fmfcmd{draw_gluon (reverse fullcircle scaled .5w shifted (.5w,.5h));} % \end{verbatim} % \begin{figure} % \begin{center} % \begin{fmfchar}(40,40) % \fmfcmd{draw_gluon (fullcircle scaled .5w shifted (.5w,.5h));} % \end{fmfchar} % \qquad % \begin{fmfchar}(40,40) % \fmfcmd{draw_gluon (reverse fullcircle scaled .5w shifted (.5w,.5h));} % \end{fmfchar} % \end{center} % \caption{Circular gluons.} % \label{fig:gluons} % \end{figure} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Limitations} % Currently the most severe limitation lies in the size of the % generated pictures. The largest number \MF{} can represent % internally is~4095.99998 and this is also the largest value any % coordinate measured in pixels can assume. At the most popular % laserprinter resolution of~300 dots per inch (dpi), this corresponds % to a horizontal and vertical extension of about~346mm, which is % plenty and we're more likely to hit the internal limits on the % complexity of a picture. However, at the proof mode resolution % of~2601.72dpi, this is reduced to slightly less than~40mm and we're % running the risk of arithmetic overflow in internal calculations much % earlier. % There are two potential solutions of different scope and complexity: % \begin{itemize} % \item{} Since John Hobby's \MP{} is now available without a % non-disclosure agreement from AT\&T, one solution is to replace % \MF{} by \MP, which doesn't suffer from the size % limitations\footnote{% % Right now, \FMF's \MP{} support is still % somewhat kludged, but the functionality is there.} % This comes with a small price paid in reduced portability of the % generated output, but as already stated above in the case of % |axodraw|, the ubiquity of PostScript printers (and the free % GhostScript interpreter) makes this a minor point. % \item{} The more ambitious solutions will be ``virtual pictures'' % (see section~\ref{sec:virtual-pictures}). % \end{itemize} % \end{fmffile} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \section*{Acknowledgements} % I am most grateful to Wolfgang Kilian, who pushed \FMF's predecessor % |feynman.mf| to its limits~\cite{Kil94}. His needs were valuable % input to \FMF. Thanks also to Angelika Himmler and Uwe Mayer for % acting as guinea pigs. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \begin{thebibliography}{99} % \bibitem{TeX} Donald E.~Knuth, \textit{The \TeX{}book}, % Addison-Wesley, Reading, 1986. % \bibitem{LaTeX} Leslie Lambort, \textit{\LaTeX{} --- A % Documentation Preparation System}, % Addison-Wesley, Reading, 1985. % \bibitem{LaTeX-Companion} Michel Goosens, Frank Mittelbach, and % Alexander Samarin, \textit{The \LaTeX{} Companion}, % Addison-Wesley, Reading, 1994. % \bibitem{MF} Donald E.~Knuth, \textit{The \MF{}book}, % Addison-Wesley, Reading, 1986. % \bibitem{MetaPost} John D.~Hobby, \textit{A User's Manual for % \MP}, Computer Science Report \#162, AT\&T Bell % Laboratories, April 1992. % \bibitem{hoenig} Alan Hoenig, \textit{When \TeX{} and \MF{} % Work Together}, in \textit{Proceedings of the 7th European % \TeX{} Conference, Prague}, p.~1, September 1992. % \bibitem{levine} Micheal J.~S.~Levine, % Comp.~Phys.~Comm.~\textbf{58} (1990) 181. % \bibitem{axodraw} Jos Vermaseren, \texttt{axodraw}. % \bibitem{mfpic} Thomas E.~Leathrum, \texttt{mfpic}. % \bibitem{madgraph} Tim Stelzer and Bill Long, \texttt{MADGRAPH}, % hep-ph/93mmxxx. % \bibitem{Kil94} Wolfgang Kilian, Doctoral Thesis, Technical % University Darmstadt, 1994. % \end{thebibliography} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \StopEventually{\PrintIndex\PrintChanges} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \section{\TeX{} macros} % It's is good practice to identify this version of the document style % option. We do this by parsing an RCS |Id| string and storing the % result in the conventional \TeX{} control sequences: % \changes{1.1}{1994/05/19}{% % Don't loose on {\tt RCS} strings even iff the dollar signs have % been removed.} % \changes{1.9}{1995/02/18}{\LaTeX~2.09 compatibility} % \begin{macrocode} %<*style> %\NeedsTeXFormat{LaTeX2e} {\def\RCS#1#2\endRCS{% \ifx$#1% \@RCS $#2 \endRCS \else \@RCS $*: #1#2$ \endRCS \fi}% \def\@RCS $#1: #2,v #3 #4 #5 #6$ \endRCS{% \gdef\filename{#2}% \gdef\fileversion{v#3}% \gdef\filedate{#4}% \gdef\docdate{#4}}% \RCS feynmf.dtx,v 1.10 1995/02/18 16:42:18 ohl Exp \endRCS}% % \end{macrocode} % And now the standard procedure: % \changes{1.4}{1994/05/27}{% % \MP{} support: identification part, include % \texttt{graphicx} and pass options.} % \begin{macrocode} %<*!mp> %\ProvidesPackage{feynmf}[\filedate\space LaTeX2e package] \typeout{Package: `feynmf' \fileversion\space <\filedate> (tho) PRELIMINARY TEST RELEASE} \wlog{English documentation \@spaces<\docdate> (tho)} % %<*mp> %\ProvidesPackage{feynmp}[\filedate\space LaTeX2e package] \typeout{Package: `feynmp' \fileversion\space <\filedate> (tho) PRELIMINARY TEST RELEASE} \wlog{English documentation \@spaces<\docdate> (tho)} % \end{macrocode} % Every option we don't understand (that is \emph{every} option) is % sent down to |graphicx|: % \begin{macrocode} %<*!209> \DeclareOption*{\PassOptionsToPackage{\CurrentOption}{graphicx}} \ProcessOptions % \end{macrocode} % For the sake of Portabilitical Correctness, we use \LaTeX's % |graphicx| for including PostScript, instead of the simpler |epsf| % which comes with |dvips| and would have sufficed % \begin{macrocode} \RequirePackage{graphicx} % %<209>\input epsf.sty % % \end{macrocode} % Compatibility macros for \LaTeX~2.09: % \begin{macrocode} %<*209> \def\InputIfFileExists#1#2#3{% \openin\@inputcheck#1 % \ifeof\@inputcheck \closein\@inputcheck #3% \else \closein\@inputcheck #2% \input{#1} \fi} \def\IfFileExists#1#2#3{% \openin\@inputcheck#1 % \ifeof\@inputcheck \closein\@inputcheck #3% \else \closein\@inputcheck #2% \fi} % % \end{macrocode} % \begin{dubious} % We should |\||mdqon| at the end only if the German extensions are % really active, not just loaded. % \end{dubious} % \begin{macrocode} \let\mdqrestore\relax \@ifundefined{mdqoff}{}{% \mdqoff \let\mdqrestore\mdqon} % \end{macrocode} % \begin{macro}{\fmfcmd} % The entrance through which our commands enter the world of % \MF. Note the |\ignorespaces|: we need to avoid spurious % blanks in the output list. % \begin{macrocode} \newwrite\@outfmf \def\fmfcmd#1{% \immediate\write\@outfmf{#1}\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\fmffile} % This environment encloses each \MF{} input file. The single % argument gives the name of the file. % \changes{1.1}{1994/05/16}{% % Stupid: {\tt fileversion} can be reset by other packages, store % the current value in {\tt fmf@fileversion} and use this one.} % \changes{1.1}{1994/05/20}{% % Pass RCS revision in a string.} % \changes{1.4}{1994/05/27}{\MP{} support: write \MP{} file.} % \changes{1.9}{1995/01/18}{% % Protect against wrong arguments to \texttt{fmffile}.} % \begin{macrocode} {\catcode`\%=11\gdef\p@rcent{%}} \edef\fmf@fileversion{\fileversion} \def\fmffile#1{% \def\thefmffile{#1}% \equaltojobname{\thefmffile}{% \errhelp={The argument of \fmffile MUST NOT be identical to the^^J% name of your main input file! I will use fmfdefault.mf^^J% this time around, but you'd better fix your code now!}% \errmessage{Invalid arument of \string\fmffile!}% \def\thefmffile{fmfdefault}}{}% %<*!mp> \immediate\openout\@outfmf=\thefmffile.mf\relax \fmfcmd{\p@rcent\space \thefmffile.mf -- do not edit, % generated automatically by \jobname.tex^^J% input feynmf^^J% require_RCS_revision "\expandafter\@gobble\fmf@fileversion";}% % %<*mp> \immediate\openout\@outfmf=\thefmffile.mp\relax \fmfcmd{\p@rcent\space \thefmffile.mp -- do not edit, % generated automatically by \jobname.tex^^J% input feynmp^^J% require_RCS_revision "\expandafter\@gobble\fmf@fileversion";}% % % \end{macrocode} % The following trick has been taken from |mfpic|~\cite{mfpic}: % proceed even if the font is not available yet, because we have to % write the \MF{} file first. % \changes{1.4}{1994/05/27}{\MP{} support: don't open \texttt{tfm} file.} % \begin{macrocode} %<*!mp> \batchmode \font\f@ynmf=\thefmffile \errorstopmode % \end{macrocode} % Inform the user: % \begin{macrocode} \ifx\f@ynmf\nullfont \def\f@ynmf{feynmf character:}% \typeout{% feynmf: File \thefmffile.tfm not found:^^J% feynmf: Process \thefmffile.mf with METAFONT and then % reprocess this file.}% \else \typeout{% feynmf: File \thefmffile.tfm found.^^J% feynmf: Nevertheless, if the picture has changed, % reprocess \thefmffile.mf.^^J% feynmf: If dimension have changed, reprocess \thefmffile.mf % and \jobname.tex.}% \fi % % \end{macrocode} % Count the characters % \begin{macrocode} \setcounter{fmfchar}{0}} \let\thefmffile\relax \newcounter{fmfchar} % \end{macrocode} % \end{macro} % \begin{macro}{\equaltojobname} % Here's a kludge for comparing strings to |\jobname|. I dont quite % understand, why the |\meaning| hack is necessary, but |\jobname| % behaves differently from other macros with respect to |\ifx|. % \begin{macrocode} \def\equaltojobname#1#2#3{% \edef\@tempa{#1}% \edef\@tempa{\meaning\@tempa}% \edef\@tempb{\jobname}% \edef\@tempb{\meaning\@tempb}% \ifx\@tempa\@tempb #2 \else #3 \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\endfmffile} % And here is how we close the |fmffile| environment: % \begin{macrocode} \def\endfmffile{% \fmfcmd{\p@rcent\space the end.^^J% end.^^J% endinput;}% \let\thefmffile\relax \immediate\closeout\@outfmf} % \end{macrocode} % \end{macro} % \begin{macro}{\fmf@char} % This is the bulk of the environment used for each ``character'' % drawn by \MF. % \changes{1.5}{1994/08/17}{% % Removed definiton of \texttt{sharp}. It's never used and % conflicts with the $\sharp$ symbol.} % \begin{macrocode} {\catcode`\#=11\gdef\sh@rp{#}} \def\fmf@char#1#2{% % \end{macrocode} % Make sure that a \MF{} file is open, otherwise \emph{really} % obscure error messages are possible: % \changes{1.3}{1994/05/23}{% % Make sure that a \MF{} file is open, otherwise \emph{really} % obscure error messages are possible.} % \begin{macrocode} \ifx\thefmffile\relax \errhelp={Outside a fmffile environment, I have no clue as to where^^J% the METAFONT commands should go. I will use fmfdefault.mf^^J% for this character, but you'd better fix your code!}% \errmessage{I detected a fmfchar environment outside of fmffile}% \fmffile{fmfdefault} \fi % \end{macrocode} % We can't use |\stepcounter| because of the |amstext| option of % AMS-\LaTeX{} disables it sometimes. % \changes{1.9}{1995/01/07}{Don't use \texttt{stepcounter}.} % \begin{macrocode} \global\expandafter\advance\csname c@fmfchar\endcsname \@ne % \end{macrocode} % Start \MF{} character: % \begin{macrocode} \fmfcmd{beginchar(\thefmfchar, #1*\the\unitlength\sh@rp, % #2*\the\unitlength\sh@rp, 0);^^J% "feynmf: \thefmfchar";}% \fmfcmd{LaTeX_unitlength:=\the\unitlength;}% \fmfinit \fmfpen{thin}} % \end{macrocode} % \end{macro} % \begin{macro}{\fmfchar} % The plain version, no labels, no enclosing |picture| environment % \begin{macrocode} \def\fmfchar(#1,#2){% \fmf@char{#1}{#2}% % \end{macrocode} % Place the character: % \changes{1.4}{1994/05/27}{\MP{} support: include PostScript file.} % \changes{1.9}{1995/02/18}{\LaTeX~2.09 compatibility} % \begin{macrocode} %{\f@ynmf \char\value{fmfchar}}% %<*mp> \leavevmode \IfFileExists{\thefmffile.\thefmfchar}% %<*!209> {\includegraphics[type=eps,ext=\thefmfchar,read=\thefmfchar]% {\thefmffile}}% % %<*209> {\epsffile{\thefmffile.\thefmfchar}}% % {\typeout{% feynmp: File \thefmffile.\thefmfchar\space not found:^^J% feynmp: Process \thefmffile.mp with MetaPost and then % reprocess this file.}}% % \ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\endfmfchar} % \begin{macrocode} \def\endfmfchar{% \fmfposition \fmfdraw \fmfcmd{endchar;}} % \end{macrocode} % \end{macro} % \begin{macro}{\fmfchar*} % The extended version, with labels and |picture| environment. % \begin{macrocode} \@namedef{fmfchar*}(#1,#2){% \begin{picture}(#1,#2) \fmf@char{#1}{#2}% % \end{macrocode} % Process the \MF{} output for labels (if any), enforcing |%| as % comment character. % \begin{macrocode} %<*!mp> {\catcode`\%=14\relax \grepfile{% \thefmffile.\thefmfchar}{% \thefmffile.log}{% \thefmffile.t\thefmfchar}}% % % \end{macrocode} % Place the character: % \changes{1.4}{1994/05/27}{\MP{} support: include PostScript file.} % \begin{macrocode} %\put(0,0){{\f@ynmf \char\value{fmfchar}}}% %<*mp> \IfFileExists{\thefmffile.\thefmfchar}% %<*!209> {\put(0,0){\includegraphics[type=eps,ext=\thefmfchar,read=\thefmfchar]% {\thefmffile}}}% % %<*209> {\put(0,0){\epsffile{\thefmffile.\thefmfchar}}}% % {\typeout{% feynmp: File \thefmffile.\thefmfchar\space not found:^^J% feynmp: Process \thefmffile.mp with MetaPost and then % reprocess this file.}}% % \ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\endfmfchar*} % \begin{macrocode} \@namedef{endfmfchar*}{% \endfmfchar % \end{macrocode} % Enforce |%| as comment character: % \begin{macrocode} {\catcode`\%=14\relax \InputIfFileExists{\thefmffile.t\thefmfchar}{}{% \typeout{% feynmf: Label file \thefmffile.t\thefmfchar\space not found:^^J% % feynmf: Process \thefmffile.mf with METAFONT and then % % feynmf: Process \thefmffile.mp with MetaPost and then % reprocess this file.}}}% \end{picture}} % \end{macrocode} % \end{macro} % \begin{macro}{\fmfframe} % This is used to allocate additional space around a |fmfchar*|, since % the labels (or the diagram itself) might overshoot. % |\fmfchar(|\meta{left}|,|\meta{top}|)(|\meta{right}|,|\meta{bottom}|){|% % \meta{box}|}| puts an invisible frame of the given dimensions % (measured in |\unitlength|) around \meta{box}. % \begin{macrocode} \def\fmfframe(#1,#2)(#3,#4)#5{% \leavevmode \hbox{\vbox{\vskip#2\unitlength\par \hbox{\hskip#1\unitlength#5\hskip#3\unitlength}\par \vskip#4\unitlength}}} % \end{macrocode} % \end{macro} % \begin{macro}{\fmfpen} % Picup a |pencircle| scaled by the argument. % \begin{macrocode} \def\fmfpen#1{\fmfcmd{pickup pencircle scaled #1;}} % \end{macrocode} % \end{macro} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Grep} % \label{sec:grep} % \begin{macro}{\grepfile} % The macro |\grepfile{|\meta{pattern}|}{|\meta{in}|}{|\meta{out}|}| % writes all lines matching |:|\meta{pattern}|:| from file \meta{in} % to file \meta{out} after stripping off the pattern. % \begin{dubious} % Pattern matching on lines with a single leading colon fails. % \end{dubious} % \changes{1.4}{1994/05/28}{% % Don't include the \texttt{grep} macros in the \MP{} version. % \texttt{write} makes them obsolete.} % \begin{macrocode} %<*!mp> \def\grepfile#1#2#3{% \begingroup % \end{macrocode} % Hash the pattern and open the input and output streams: % \begin{macrocode} \edef\pattern{\csname*grep*#1*\endcsname}% \immediate\openin\grep@infile #2\relax \ifeof\grep@infile \else \grep@outopenfalse % \end{macrocode} % Don't add anything at the end of input lines and don't expand % anything we've read from the file: % \begin{macrocode} \endlinechar=-1 \catcode`\\=12\relax % \end{macrocode} % Loop over the input lines until end of file occurs: % \begin{macrocode} \loop \read\grep@infile to \grep@lbuf \ifeof\grep@infile \grep@contfalse \else \grep@conttrue % \end{macrocode} % Iff the input line is not empty, use |\grep@aline| to examine its % contents and, iff the pattern matched, write a line to the output file. % \begin{macrocode} \ifx\grep@lbuf\empty \else \expandafter\grep@aline\grep@lbuf\sentinel \ifx\pattern\grep@tag % \end{macrocode} % Delayed open (this avoids empty files): % \begin{macrocode} \ifgrep@outopen \else \immediate\openout\grep@outfile #3\relax \immediate\write\grep@outfile{\p@rcent\space #3 % -- generated automatically from #2}% \immediate\write\grep@outfile{\p@rcent\space Think twice before editing THIS file!}% \grep@outopentrue \fi \immediate\write\grep@outfile{\grep@val}% \fi \fi \fi \ifgrep@cont \repeat % \end{macrocode} % Close the files after we're done. % \changes{1.1}{1994/05/16}{% % Stupid: {\tt closein} the input stream, don't use {\tt closeout} on it.} % \begin{macrocode} \ifgrep@outopen \immediate\closeout\grep@outfile \fi \fi \immediate\closein\grep@infile \endgroup} % \end{macrocode} % \end{macro} % \begin{macro}{\grep@infile} % \begin{macro}{\grep@outfile} % The I/O streams for the grep facility % \begin{macrocode} \newread\grep@infile \newwrite\grep@outfile % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\ifgrep@cont} % \begin{macro}{\ifgrep@outopen} % and flags for the same % \begin{macrocode} \newif\ifgrep@cont \newif\ifgrep@outopen % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\grep@aline} % Examine one line and set the variables |\grep@tag| and |\grep@val| % iff the line starts with a colon. Subtle point here: |\ifx#1:| will % \emph{not} work if |#1| starts with a |{| followed by two identical % characters. % \begin{macrocode} \def\grep@aline#1#2\sentinel{% \ifx:#1% \grep@splitlbuf#2\sentinel \else \edef\grep@tag{\csname*grep*\endcsname}% \def\grep@val{}% \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\grep@splitlbuf} % Split the line buffer at the remaining colon, hashing the first part. % \begin{macrocode} \def\grep@splitlbuf#1:#2\sentinel{% \edef\grep@tag{\csname*grep*#1*\endcsname}% \def\grep@val{#2}} % % \end{macrocode} % \end{macro} % The other \TeX{} command sequences are defined below, along with the % \MF{} macros they are in one-to-one correspondence to. % \begin{macrocode} % % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \section{\MF{} macros} % \label{sec:mf-code} % Now we turn our attention to the \MF{} % macros. % \begin{dubious} % We should find a way (a hack) to index the % \MF{} macros with the |doc| option. % \end{dubious} % Because to name clashes, \FMF{} will not work if the |cmbase| is % loaded. Die with an useful error message: % \changes{1.5}{1994/06/13}{Don't accept the Computer Modern Base.} % \begin{macrocode} %<*base> if known cmbase: errhelp "feynmf will only work with plain Metafont, as described in the book."; errmessage "feynmf: CMBASE detected. Please use the PLAIN base."; forever: errmessage "No use in trying! You'd better eXit now ..."; errorstopmode; endfor % \end{macrocode} % Make the RCS revision number available for feature testing: % \changes{1.1}{1994/05/20}{% % Handle arbitrary RCS revision strings.} % \begin{macrocode} vardef parse_RCS (suffix RCS) (expr s) = save n, c; numeric n, RCS[]; string c; RCS[0] := 0; for n = 1 upto length (s): c := substring (n-1,n) of s; exitif ((RCS[0] > 0) and (c = " ")); if ((c = "0") or (c = "1") or (c = "2") or (c = "3") or (c = "4") or (c = "5") or (c = "6") or (c = "7") or (c = "8") or (c = "9")): if RCS[0] = 0: RCS[0] := 1; RCS[RCS[0]] := 0; fi RCS[RCS[0]] := 10 * RCS[RCS[0]] + scantokens (c); elseif c = ".": RCS[0] := RCS[0] + 1; RCS[RCS[0]] := 0; else: fi endfor enddef; % \end{macrocode} % Check that \LaTeX{} style and \MF{} macros are in sync: % \begin{macrocode} vardef require_RCS_revision expr s = save n, TeX_rev, mf_rev; numeric n; parse_RCS (TeX_rev, s); parse_RCS (mf_rev, "1.10"); for n = 1 upto min (2, TeX_rev[0], mf_rev[0]): if TeX_rev[n] > mf_rev[n]: errhelp "Your version of `feynmf.sty' is higher that of your `feynmf.mf'."; errmessage "feynmf: Metafont macros out of date"; elseif TeX_rev[n] < mf_rev[n]: errhelp "Your version of `feynmf.mf' is higher that of your `feynmf.sty'."; errmessage "feynmf: LaTeX style out of date"; fi exitif (TeX_rev[n] <> mf_rev[n]); endfor enddef; % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{\MP{} Kludges} % This \MP{} support is still kludgey, but it works and we're trying % to prove a point. % \changes{1.4}{1994/05/27}{Preliminary \MP{} support: mimic \MF.} % \begin{macrocode} %<*mp> vardef cullit = \ enddef; % \end{macrocode} % \begin{macrocode} vardef beginchar (expr c, wd, ht, dp) = LaTeX_file := ""; beginfig(c); w:=wd; h:=ht; enddef; string LaTeX_file; % \end{macrocode} % \begin{macrocode} vardef endchar = setbounds currentpicture to (0,0)--(w,0)--(w,h)--(0,h)--cycle; if LaTeX_file <> "": write EOF to LaTeX_file; LaTeX_file := ""; endfig enddef; % \end{macrocode} % Sharped dimensions are useless with \MP. We define them anyway % with trivial translation, so that the \MF{} code can be used % unchanged. % \begin{macrocode} bp# := bp; cc# := cc; cm# := cm; dd# := dd; in# := in; mm# := mm; pc# := pc; pt# := pt; % \end{macrocode} % As I said: trivial translation. % \begin{macrocode} vardef define_blacker_pixels(text t) = forsuffixes $=t: $:=$.#; endfor enddef; % % \end{macrocode} % \begin{macrocode} %mode_setup; % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Basics} % \label{sec:mf-basics} % Allow the user to life dangerously or not, depending on his % preferences. % \changes{1.7}{1994/10/23}{\texttt{fmfwizard}: to live dangerously or not.} % \begin{macrocode} boolean feynmfwizard; feynmfwizard := false; % % \end{macrocode} % \begin{macro}{\fmfwizard} % \begin{macro}{\fmfnowizard} % \begin{macrocode} %<*style> \def\fmfwizard{\fmfcmd{feynmfwizard := true;}} \def\fmfnowizard{\fmfcmd{feynmfwizard := false;}} % % \end{macrocode} % \end{macro} % \end{macro} % Default values of style parameters: % \begin{macrocode} %<*base> thin#:=1pt#; % dimension of the lines thick#:=2thin#; arrow_len# := 4mm#; arrow_ang := 15; curly_len#:=3mm#; dash_len#:=3mm#; % 'photon' lines dot_len#:=2mm#; % 'photon' lines wiggly_len#:=4mm#; % 'photon' lines wiggly_slope:=60; shade_black#:=1pt#; % shading shade_white#:=2shade_black#; shade_angle:=60; decor_size#:=5mm#; dot_size#:=2thick#; % \end{macrocode} % Convert ``sharp'' units: % \begin{macrocode} define_blacker_pixels (thick, thin, shade_black, shade_white, dash_len, dot_len, wiggly_len, curly_len, arrow_len, decor_size, dot_size); % \end{macrocode} % Back by popular demand: shrinking dimensions. % \changes{1.5}{1994/06/13}{% % Back by popular demand: shrinking dimensions.} % \begin{macrocode} def shrink expr s = begingroup if shrinkables <> "": save tmp_; forsuffixes $ = scantokens shrinkables: tmp_ := $.#; save $; $.# := s * tmp_; endfor define_blacker_pixels (scantokens shrinkables); enddef; % \end{macrocode} % \begin{macrocode} def endshrink = endgroup enddef; % % \end{macrocode} % \begin{macro}{\fmfshrink} % \begin{macro}{\endfmfshrink} % Exporting the whole enchilada to \LaTeX: % \begin{macrocode} %<*style> \def\fmfshrink#1{\fmfcmd{shrink (#1);}} \def\endfmfshrink{\fmfcmd{endshrink;}} % % \end{macrocode} % \end{macro} % \end{macro} % \begin {macrocode} %<*base> string shrinkables; shrinkables := ""; % \end{macrocode} % This macro is used to register shrinkable dimensions. It is not % really robust, we have add the first enty by hand: % \begin {macrocode} vardef addto_shrinkables (text l) = forsuffixes $ = l: shrinkables := shrinkables & "," & str $; endfor enddef; shrinkables := "thick,thin"; % \end{macrocode} % \begin {macrocode} addto_shrinkables (shade_black, shade_white); addto_shrinkables (dash_len, dot_len); addto_shrinkables (wiggly_len, curly_len); addto_shrinkables (arrow_len); addto_shrinkables (decor_size, dot_size); % \end{macrocode} % Default to metric units, but this will be reset by |\begin{fmfchar}| % anyway. % \begin {macrocode} LaTeX_unitlength := mm; % \end{macrocode} % Count the number of tokens in the argument: % \begin {macrocode} vardef count (text list) = forsuffixes $ = list: + 1 endfor enddef; % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Parsing options} % \label{sec:getopt} % Parse the string |s| into comma separated tokens |opt[]|, ignoring % blanks before |=|'s. Double commas are passed as a single comma. % \changes{1.9}{1994/10/25}{% % Plugged the string memory leak in \texttt{getopt}: don't create % intermediate one character strings, \MF{} never claims them back.} % \begin {macrocode} vardef getopt (suffix opt) (expr s) = save n, argp, escape, anchor, skip; numeric opt.first, opt.last, n, anchor; string opt[], opt[]arg; boolean opt[]tainted, argp, escape, skip; opt.first := 0; opt.last := 0; opt[opt.last] := ""; argp := false; escape := false; anchor := 0; skip := true; for n = 1 upto length (s): % \end{macrocode} % Skip blanks at the beginning of each option or argument: % \begin {macrocode} if skip and (substring (n-1, n) of s = " "): anchor := anchor + 1; else: skip := false; % \end{macrocode} % If we see a comma which has not been escaped, check for a second % comma and set the |escape| flags and remember to remove the second % comma later or reset the |argp| flag, as appropriate: % \begin {macrocode} if not escape and (substring (n-1, n) of s = ","): if substring (n, n+1) of s = ",": escape := true; opt[opt.last]tainted := true; % \end{macrocode} % Else accept the option or argument: % \begin {macrocode} else: if argp: opt[opt.last]arg := substring (anchor, n-1) of s; else: opt[opt.last] := substring (anchor, n-1) of s; fi anchor := n; argp := false; skip := true; opt.last := opt.last + 1; fi % \end{macrocode} % Start as argument and ignore |=|'s until the next option: % \begin {macrocode} elseif not argp and (substring (n-1, n) of s = "="): opt[opt.last] := substring (anchor, n-1) of s; anchor := n; argp := true; skip := true; % \end{macrocode} % Accept the next character (either option or argument) and reset the % |escape| flag: % \begin {macrocode} elseif argp or (substring (n-1, n) of s <> " "): escape := false; fi fi endfor % \end{macrocode} % Accept the final option or argument: % \begin {macrocode} if argp: opt[opt.last]arg := substring (anchor, length s) of s; else: opt[opt.last] := substring (anchor, length s) of s; % \end{macrocode} % We still have to remove possible doubled commata from the arguments. % Theoretically, we could already have done it above (that's the way % earlier versions of \FMF{} did it), but only at the expense of % excessive copying of strings (like |opt[n]arg:=opt[n]arg&c|). Given % \MF's string handling, we should avoid these \emph{at any cost}, % because the wasted string memory will \emph{never} be % reclaimed!\footnote{Actually, \MP{} has code to compact the string % pool, which makes \emph{a lot} of difference in the present case. % But this doesn't help us with \MF.} % Since the more elegant former version had a serious string memory % leak, we'd better stick to the current ugly but space efficient % implementation. % \begin {macrocode} for n = opt.first upto opt.last: if known opt[n]tainted: if opt[n]tainted: opt[n]arg := untaint_string opt[n]arg; fi fi endfor enddef; % \end{macrocode} % Turn double commata into single commata, using as little string % copies as possible: % \begin {macrocode} vardef untaint_string suffix s = save n, anchor; numeric n, anchor; anchor := 0; for n = 1 upto length (s) - 1: if substring (n-1,n+1) of s = ",,": substring (anchor, n-1) of s & hide (anchor := n) fi endfor substring (anchor, length s) of s enddef; % \end{macrocode} % Split a string into |.|-separated components for matching options. % \begin {macrocode} vardef split_string (suffix comp) (expr s) = save n, anchor; numeric comp.first, comp.last, n, anchor; string comp[]; comp.first := 0; comp.last := 0; comp[comp.last] := ""; anchor := 0; for n = 1 upto length (s): if substring (n-1,n) of s = ".": comp[comp.last] := substring (anchor, n-1) of s; comp.last := comp.last + 1; anchor := n; fi endfor comp[comp.last] := substring (anchor, length s) of s; enddef; % \end{macrocode} % Return |true| iff |prefix| is a prefix of |s|: % \begin {macrocode} vardef match_prefix (expr prefix, s) = (prefix = substring (0, length prefix) of s) enddef; % \end{macrocode} % Match options similarly to |Xt| resource strings, but allowing for % abbreviations: % \changes{1.7}{1994/10/23}{More general option parsing.} % \begin {macrocode} vardef match_option (expr s, option) = save sc, optionc, n, i; numeric sc.first, sc.last, optionc.first, optionc.last; string sc[], optionc[]; numeric n, i; split_string (sc, s); split_string (optionc, option); n := sc.last - sc.first; if n <> (optionc.last - optionc.first): false else: true for i = 0 upto n: and match_prefix (sc[sc.first+i], optionc[optionc.first+i]) endfor enddef; % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Manipulating \texttt{picture}s} % \label{sec:pictures} % |save_picture (list_of_pictures)| |save|'s each member of % |list_of_pictures| inside a group and reinitializes them as nullpictures. % \begin{macrocode} def save_picture text t = save t; picture t; forsuffixes p=t: p:=nullpicture; endfor enddef; % \end{macrocode} % |begin_sketch| pushes the sketchpad stack and perform the following % drawing commands (upto the next |end_sketch|) on the new sketchpad. % \begin{macrocode} def begin_sketch = begingroup save_picture currentpicture; sketchlevel := sketchlevel+1; enddef; % \end{macrocode} % |end_sketch| pops the sketchpad stack. % \begin{macrocode} def end_sketch = sketchlevel := sketchlevel-1; sketchpad[sketchlevel] := currentpicture; endgroup enddef; % \end{macrocode} % \begin{macrocode} picture sketchpad[]; sketchlevel := 1; % \end{macrocode} % |use_sketch (transformation)| copies the transformed sketchpad into % the current picture. % \begin{macrocode} vardef use_sketch text t = addto currentpicture also (sketchpad[sketchlevel] t) enddef; % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Shading} % \label{sec:shading} % |shade (path_arg)| shades the interior of |path_arg|. This shading is % controlled by the global variables |shade_black|, |shade_white|, and % |shade_angle|. % Caveat: The procedure is only guaranteed to work for convex paths. % \begin{dubious} % \MP{} has nice primitives to aid in finding bounding boxes, in % \MF{} we have to rely on heuristics. % \end{dubious} % \begin{macrocode} vardef shade expr p_arg = save x,y,d,p,currentpen; path p; pen currentpen; % push pen! pickup pencircle scaled shade_black; p = p_arg rotated - shade_angle; % calculate enclosing rectangle x2' = x3' = xpart directionpoint up of p; % (rotated by |shade_angle|). x1' = x4' = xpart directionpoint down of p; y1' = y2' = ypart directionpoint right of p; y3' = y4' = ypart directionpoint left of p; forsuffixes $=1,2,3,4: z$ = z$' rotated shade_angle; endfor d = abs(z1-z4); % height. begin_sketch % fill rectangle with lines. for k=shade_white/d step (shade_white+shade_black)/d until 1 - shade_white/d: cutdraw k[z1,z4] -- k[z2,z3]; endfor % \end{macrocode} % \MF{} has no clipping operation, but since we know the bounding box, % we can use \MF's pixel arithmetic for calculating the set % theoretical intersection of the interior of |p_arg| and the diagonal % lines in the bounding box: % \begin{macrocode} %<*!mp> cullit; fill p_arg; unfill z1--z2--z3--z4--cycle; cullit; % % \end{macrocode} % \MP{} has clipping build in but no pixel arithmetic: % \changes{1.4}{1994/05/28}{\MP{} support: shading.} % \begin{macrocode} %<*mp> clip currentpicture to p_arg; % end_sketch; use_sketch; enddef; % \end{macrocode} % Hatching is implemented as double shading. % \changes{1.7}{1994/10/22}{Hatched vertices.} % \begin{macrocode} vardef hatch expr p = shade p; save a; a = shade_angle; save shade_angle; shade_angle = a + 90; shade p; enddef; % \end{macrocode} % |filldraw|'s sisters: % \begin{macrocode} vardef shadedraw expr p = shade p; draw p; enddef; vardef hatchdraw expr p = hatch p; draw p; enddef; % \end{macrocode} % John Hobby has a particulary nice |arrowhead| macro in plain \MP. A % variation on that theme adapted to our needs is: % \changes{1.5}{1994/10/20}{New arrows, which look better on curved arcs.} % \begin{macrocode} vardef arrow expr p = save t, a, z_, ap_, tip; numeric t[], a; pair z_, tip; path ap_; a = angle direction .5 length(p) of p; z_ = point .5 length(p) of p; (t1,whatever) = p intersectiontimes (halfcircle scaled 2/3arrow_len rotated (a+90) shifted z_); (t2,whatever) = p intersectiontimes (halfcircle scaled 4/3arrow_len rotated (a-90) shifted z_); % \end{macrocode} % |intersectiontimes| can fail, typically if the path is too short: % protect against it % \changes{1.6}{1994/10/21}{Fix arrows on too short arcs.} % \begin{macrocode} if t1 = -1: t1 := 0; fi if t2 = -1: t2 := length p; fi tip = point t2 of p; ap_ = subpath (t1,t2) of p shifted -tip; (ap_ rotated arrow_ang forced_join reverse ap_ rotated -arrow_ang -- cycle) shifted tip enddef; % \end{macrocode} % Join two paths |p| and |q| even if they don't fit exactly by % adjusting their common point. This is necessary in |arrow| because % rounding errors might induce a small mismatch even if we \emph{know} % that they should match theoretically. This is certainly a kludge % and should be used with care, but it works. % \begin{macrocode} tertiarydef p forced_join q = subpath (0, length p - 1) of p & point (length p - 1) of p .. controls postcontrol (length p - 1) of p and precontrol infinity of p .. .5[point infinity of p, point 0 of q] .. controls postcontrol 0 of q and precontrol 1 of q .. point 1 of q & subpath (1, infinity) of q enddef; % \end{macrocode} % |cut_decors| expands to a subpath of |path_arg|, excluding the % decoration at the vertices. % \changes{1.7}{1994/10/22}{Cut general vertex decorations.} % \begin{macrocode} vardef cut_decors (suffix from) (expr p) (suffix to) = subpath (if known from.decor.shape: xpart (p intersectiontimes (from.decor.shape scaled from.decor.size shifted from.loc)) else: 0 fi, if known to.decor.shape: xpart (p intersectiontimes (to.decor.shape scaled to.decor.size shifted to.loc)) else: infinity fi) of p enddef; % \end{macrocode} % The function |make_blob| is the working horse of |draw_blob|. % \begin{macrocode} vardef make_blob (expr z_arg, diameter) = save p,currentpen; path p; pen currentpen; pickup pencircle scaled thick; p = fullcircle scaled diameter shifted z_arg; shadedraw p; enddef; % \end{macrocode} % |draw_blob (pair_arg, diameter)| draws a shaded blob of diameter % |diameter| centered at |pair_arg|. The thickness of the border is % controlled by the global variable |thick|. % Hint: It saves time to draw blobs of the same size in sequence. % \begin{macrocode} vardef draw_blob (expr z_arg, diameter) = if sketched_blob_diameter <> diameter: % drawn lately? begin_sketch make_blob (origin, diameter); end_sketch; % redo hard work! sketched_blob_diameter:= diameter; % record it use_sketch shifted z_arg; % the easy way ... enddef; % \end{macrocode} % |force_new_blob| forces the redrawing of a blob of the same diameter % (in case you only changed the shading parameters). % \begin{macrocode} def force_new_blob = sketched_blob_diameter := -1; enddef; force_new_blob; % initialize it. % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Drawing} % \label{sec:drawing} % Easier than % \begin{equation} % \int_0^1 dt \left\vert\frac{dx(t)}{dt}\right\vert % \end{equation} % with the integrand the square root of a fourth order polynomial, but % sufficient for all practical purposes is % \begin{macrocode} vardef pixlen (expr p, n) = for k=1 upto length(p): + segment_pixlen (subpath (k-1,k) of p, n) endfor enddef; % \end{macrocode} % \begin{macrocode} vardef segment_pixlen (expr p, n) = for k=1 upto n: + abs (point k/n of p - point (k-1)/n of p) endfor enddef; % \end{macrocode} % |wiggly (path_arg)| expands to a ``wiggled'' version of |path_arg|. The % slope of the wiggles is controlled by the global variable |wiggle_slope|, % the length of the wiggles by the global variable |wiggly_len|. % \begin{macrocode} vardef wiggly expr p_arg = save wpp; numeric wpp; wpp = ceiling (pixlen (p_arg, 10) / (wiggly_len * length(p_arg))); for k=0 upto wpp*length(p_arg) - 1: point k/wpp of p_arg {direction k/wpp of p_arg rotated wiggly_slope} .. point (k+.5)/wpp of p_arg {direction (k+.5)/wpp of p_arg rotated - wiggly_slope} .. endfor if cycle p_arg: cycle else: point infinity of p_arg fi enddef; % \end{macrocode} % |curly (path_arg)| expands to a ``curly'' version of |path_arg|. The % the length of the curls is controlled by the global variable % |curly_len|. % \begin{macrocode} vardef curly expr p_arg = save cpp; numeric cpp; cpp = ceiling (pixlen (p_arg, 10) / (curly_len * length(p_arg))); if cycle p_arg: for k=0 upto cpp*length(p_arg) - 1: point (k+.33)/cpp of p_arg {direction (k+.33)/cpp of p_arg rotated 90} .. point (k-.33)/cpp of p_arg {direction (k-.33)/cpp of p_arg rotated -90} .. endfor cycle else: point 0 of p_arg {direction 0 of p_arg rotated -90} .. for k=1 upto cpp*length(p_arg) - 1: point (k+.33)/cpp of p_arg {direction (k+.33)/cpp of p_arg rotated 90} .. point (k-.33)/cpp of p_arg {direction (k-.33)/cpp of p_arg rotated -90} .. endfor point infinity of p_arg {direction infinity of p_arg rotated 90} enddef; % \end{macrocode} % An inventory of valid line styles is implemented as a hash table: % \begin{macrocode} save vsty_hash; % \end{macrocode} % This is a bit like |mode_def| in plain \MF{} but doesn't use an % array of available modes: |style_def "foo"| will define a macro % |draw_foo| drawing a line of a certain style along any given path: % \begin{macrocode} def style_def suffix s = vsty_hash.s := 1; expandafter quote vardef scantokens ("draw_" & str s) enddef; % \end{macrocode} % Let \MF{} do the lookup: suffices % \begin{macrocode} vardef vsty_exists suffix s = known vsty_hash.s enddef; % \end{macrocode} % an strings % \begin{macrocode} vardef valid_style expr s = expandafter vsty_exists scantokens (s) enddef; % \end{macrocode} % \changes{1.9}{1994/11/21}{Enhance and streamline the line styles.} % |phantom| lines are simple, even with arrows. % \begin{macrocode} style_def phantom expr p = enddef; style_def phantom_arrow expr p = fill (arrow p); enddef; % \end{macrocode} % |plain| lines aren't harder. % \begin{macrocode} style_def plain expr p = draw p; enddef; style_def plain_arrow expr p = draw p; fill (arrow p); enddef; style_def dbl_plain expr p = draw_double p; enddef; style_def dbl_plain_arrow expr p = draw_double_arrow p; enddef; % \end{macrocode} % Wiggly lines use |wiggly| from above % \begin{macrocode} style_def wiggly expr p = draw (wiggly p); enddef; style_def dbl_wiggly expr p = draw_double (wiggly p); enddef; % \end{macrocode} % and curly lines use |curly| from above % \begin{macrocode} style_def curly expr p = draw (curly p); enddef; style_def dbl_curly expr p = draw_double (curly p); enddef; % \end{macrocode} % |draw_dashes (p)| draws a dashed line on |p| % \changes{1.4}{1994/05/27}{% % Rename the line style \texttt{dashed} to \texttt{dashes}, to avoid % a name clash with \MP.} % \begin{macrocode} style_def dashes expr p_arg = save dpp; numeric dpp; dpp = ceiling (pixlen (p_arg, 10) / (dash_len * length(p_arg))); for k=0 upto dpp*length(p_arg) - 1: draw point k/dpp of p_arg .. point (k+.5)/dpp of p_arg; endfor enddef; style_def dbl_dashes expr p = save dpp; numeric dpp; dpp = ceiling (pixlen (p, 10) / (dash_len * length(p))); for k=0 upto dpp*length(p) - 1: draw_double point k/dpp of p .. point (k+.5)/dpp of p; endfor enddef; style_def dbl_dashes_arrow expr p = draw_dbl_dashes p; fill (arrow p); enddef; style_def dashes_arrow expr p = draw_dashes p; fill (arrow p); enddef; % \end{macrocode} % |draw_dots (expr p_arg)| draws a dotted line on |path_arg| % \changes{1.4}{1994/05/27}{% % Rename the line style \texttt{dotted} to \texttt{dots}, to be % consistent with \texttt{dashes}.} % \begin{macrocode} style_def dots expr p_arg = save dpp; numeric dpp; dpp = ceiling (pixlen (p_arg, 10) / (dot_len * length(p_arg))); for k=0 upto dpp*length(p_arg): drawdot point k/dpp of p_arg; endfor enddef; style_def dbl_dots expr p_arg = save dpp; numeric dpp; dpp = ceiling (pixlen (p_arg, 10) / (dot_len * length(p_arg))); begingroup pen oldpen; oldpen := currentpen; pickup oldpen scaled 3; % draw a thick linn for k=0 upto dpp*length(p_arg): drawdot point k/dpp of p_arg; endfor pickup oldpen; cullit; for k=0 upto dpp*length(p_arg): undrawdot point k/dpp of p_arg; endfor cullit; % and remove the stuffing endgroup; enddef; style_def dbl_dots_arrow expr p = draw_dbl_dots p; fill (arrow p); enddef; style_def dots_arrow expr p = draw_dots p; fill (arrow p); enddef; % \end{macrocode} % |draw_double (expr p_arg)| draws a double line. % \begin{macrocode} style_def double expr p_arg = begingroup pen oldpen; oldpen := currentpen; pickup oldpen scaled 3; % draw a thick linn draw p_arg; pickup oldpen; cullit; undraw p_arg; cullit; % and remove the stuffing endgroup; enddef; style_def double_arrow expr p = draw_double p; fill (arrow p); enddef; % \end{macrocode} % Old aliases: % \begin{macrocode} style_def vanilla expr p = draw_plain p enddef; style_def fermion expr p = draw_plain_arrow p enddef; style_def quark expr p = draw_plain_arrow p enddef; style_def electron expr p = draw_plain_arrow p enddef; style_def photon expr p = draw_wiggly p enddef; style_def boson expr p = draw_wiggly p enddef; style_def gluon expr p = draw_curly p enddef; style_def heavy expr p = draw_dbl_plain_arrow p enddef; style_def ghost expr p = draw_dots_arrow p enddef; style_def scalar expr p = draw_dashes_arrow p enddef; % \end{macrocode} % More old aliases: % \begin{macrocode} vardef fermion expr path_arg = fill arrow (path_arg); path_arg enddef; vardef photon expr path_arg = wiggly path_arg enddef; vardef gluon expr path_arg = curly path_arg enddef; % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Graphs of vertices} % \label{sec:graphs} % Here is the fun part of \FMF: \emph{automagic} placement of % vertices. % \begin{macrocode} %tracingmacros:=1; %tracingonline:=1; tracingstats:=1; % \end{macrocode} % You can say |vtracing:=true| to see what's going on. % \begin{macrocode} boolean vtracing; vtracing := false; % true % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsubsection{Data structures} % \begin{table} % \begin{tabular}{lll} % Type & Name & Purpose \\\hline % |numeric| & |vlist.first| & pointer to first vertex (usually 1) \\ % |numeric| & |vlist.last| & pointer to last vertex (starts with 0) \\ % |string| & |vlist[|$i$|]name| & symbolic name of the vertex\\ % |pair| & |vlist[|$i$|]loc| & position of the vertex \\ % |string| & |vlist[|$i$|]lbl| & label \\ % |numeric| & |vlist[|$i$|]lbl.ang| & angle \\ % |numeric| & |vlist[|$i$|]lbl.dist| & distance \\ % |path| & |vlist[|$i$|]decor.shape| & shape of decoration\\ % |numeric| & |vlist[|$i$|]decor.size| & size of decoration\\ % |numeric| & |vlist[|$i$|]decor.sty| & filling style of decoration\\ % |numeric| & |vlist[|$i$|]decor.ang| & rotation angle\\ % |numeric| & |vlist[|$i$|]arc.first| & pointer to first arc \\ % |numeric| & |vlist[|$i$|]arc.last| & pointer to last arc \\ % |numeric| & |vlist[|$i$|]arc[|$j$|]| & $j$th arc of the $i$th vertex \\ % |string| & |vlist[|$i$|]arc[|$j$|]sty| & style of the arc\\ % |numeric| & |vlist[|$i$|]arc[|$j$|]tns| & tension of the arc\\ % |string| & |vlist[|$i$|]arc[|$j$|]lsr| & left, straight, right\\ % |string| & |vlist[|$i$|]arc[|$j$|]lbl| & label\\ % |string| & |vlist[|$i$|]arc[|$j$|]lbl.side|& side of the label\\ % |numeric| & |vlist[|$i$|]arc[|$j$|]lbl.dist|& distance of the label % \end{tabular} % \caption{Vertex data structure} % \label{tab:VDS} % \end{table} % The data structure for our graph is shown in % table~\ref{tab:VDS}\footnote{% % \begin{dubious} % \texttt{boolean vlist[i]arc[j]smooth} will indicate that this % arc belongs to a set of arcs which are to be smoothly connected. % The implementation will start by going to the strt of this set, % define a long smooth path and finally do the drawing on the % various subpaths. % \end{dubious}}. % \MF{} turns out to be quite powerful, providing such constructs % in an unconventional, but flexible and concise way. While we use % |save vhash| to forget all previously defined vertices, we leave % |vlist| alone, because we will know from $|vlist.last| < % |vlist.first|$ that it's empty. Note that we can't |vardef| this % because then the |save| would go inside a group. % \begin{macrocode} def vinit = save vhash; numeric vlist.first, vlist.last; vlist.first := 1; vlist.last := 0; pair vlist[]loc, lambda[][]; numeric vlist[]decor.size, vlist[]decor.sty, vlist[]decor.ang, vlist[]arc.first, vlist[]arc.last, vlist[]arc[], vlist[]arc[]lsr, vlist[]arc[]tns, vlist[]arc[]lbl.dist, vlist[]constr.first, vlist[]constr.last, vlist[]constr[]; string vlist[]name, vlist[]lbl, vlist[]arc[]sty, vlist[]arc[]lbl, vlist[]arc[]lbl.side; numeric vlist[]lbl.ang, vlist[]lbl.side; path vlist[]decor.shape; enddef; % % \end{macrocode} % \begin{macro}{\fmfinit} % We can also ask for initialization explicitely from \TeX{} (usually % it is called implicitely by |\begin{fmfchar}|). This flushes the % vertex table. % \begin{macrocode} % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % Here are the ``galleries'' we're hooking our external vertices on % (see also the pictures on page~\pageref{p:galleries}): % \begin{macrocode} %<*base> vardef left_gallery = (.1w,0)..(0,.5h)..(.1w,h) enddef; vardef right_gallery = (.9w,0)..(w,.5h)..(.9w,h) enddef; vardef bottom_gallery = (0,.1h)..(.5w,0)..(w,.1h) enddef; vardef top_gallery = (0,.9h)..(.5w,h)..(w,.9h) enddef; vardef surround_gallery = superellipse ((w,.5h), (.5w,h), (0,.5h), (.5w,0), .75) enddef; % \end{macrocode} % and the \MF{} code which does the hard work for the above % \TeX{} macros % \begin{macrocode} vardef vleft (text vl) = vdistribute (left_gallery, vl) enddef; vardef vright (text vl) = vdistribute (right_gallery, vl) enddef; vardef vbottom (text vl) = vdistribute (bottom_gallery, vl) enddef; vardef vtop (text vl) = vdistribute (top_gallery, vl) enddef; vardef vsurround (text vl) = vdistribute (surround_gallery, vl) enddef; % \end{macrocode} % Distribute the vertices in the list |vl| evenly along the path |p|: % \begin{macrocode} vardef vdistribute (expr p) (text vl) = save numv, len, off; numeric numv, len, off; numv = count (vl); % \end{macrocode} % If the path is cyclic, place the first vertex twice: % \begin{macrocode} if cycle p: numv := numv + 1; fi len := length (p); if numv = 1: vforce (point len/2 of p, vl); else: off := 0; forsuffixes $ = vl: vforce (point off of p, $); off := off + len/(numv-1); endfor enddef; % % \end{macrocode} % \begin{macro}{\fmfleftn} % \begin{macro}{\fmfrightn} % \begin{macro}{\fmfbottomn} % \begin{macro}{\fmftopn} % \begin{macro}{\fmfsurroundn} % A short cut: % \begin{macrocode} %<*style> \def\fmfleftn#1#2{\fmfcmd{vleftn(#1,#2);}} \def\fmfrightn#1#2{\fmfcmd{vrightn(#1,#2);}} \def\fmfbottomn#1#2{\fmfcmd{vbottomn(#1,#2);}} \def\fmftopn#1#2{\fmfcmd{vtopn(#1,#2);}} \let\fmfincomingn\fmfleftn \let\fmfoutgoingn\fmfrightn \def\fmfsurroundn#1#2{\fmfcmd{vsurroundn(#1,#2);}} % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macrocode} %<*base> def vmklist (suffix v) (expr n) = for $ = 1 upto n-1: v[$], endfor v[n] enddef; % \end{macrocode} % \begin{macrocode} vardef vleftn (suffix v) (expr n) = vleft (vmklist (v, n)); enddef; vardef vrightn (suffix v) (expr n) = vright (vmklist (v, n)); enddef; vardef vbottomn (suffix v) (expr n) = vbottom (vmklist (v, n)); enddef; vardef vtopn (suffix v) (expr n) = vtop (vmklist (v, n)); enddef; vardef vsurroundn (suffix v) (expr n) = vsurround (vmklist (v, n)); enddef; % % \end{macrocode} % \begin{macro}{\fmffor} % \begin{macro}{\endfmffor} % \begin{macrocode} %<*style> \def\fmffor#1#2#3#4{\fmfcmd{for #1 = #2 step #3 until #4:}} \def\endfmffor{\fmfcmd{endfor}} % % \end{macrocode} % \end{macro} % \end{macro} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsubsection{Choosing a Layout for the Graph} % The procedure |vposition| is called near the end and % chooses ``optimal'' vertex positions by minimizing the sum of the % weighted lengths of the arcs. Since the quantity to be optimized is % quadratic in the vertices % \begin{equation} % L = \frac{1}{2} \sum_i \sum_{j\in\alpha(i)} % t_{ij} (\vec v_i - \vec v_j)^2\,, % \end{equation} % where~$\alpha(i)$ denotes the set of vertices connectes with the % vertex~$i$, we just have to solve a system of linear equations. % Adding Lagrange multipliers~$\lambda_{ij}$ for the constraints that % have been specified % \begin{equation} % \Lambda = \sum_i \sum_{j\in\gamma(i) \atop j>i} % \vec\lambda_{ij}\cdot(\vec v_i - \vec v_j - \vec d_{ij})\,, % \end{equation} % where~$\gamma(i)$ denotes the set of vertices which have a fixed % distance to the vertex~$i$, the set of linear equations is given by % \begin{eqnarray} % 0 & = & \frac{\partial}{\partial \vec v_i} (L+\Lambda) % = \sum_{j\in\alpha(i)} t_{ij} (\vec v_i - \vec v_j) % + \sum_{j\in\gamma(i) \atop j>i} \vec\lambda_{ij} % - \sum_{j\in\gamma(i) \atop j vardef vposition = for i = vertices: % \end{macrocode} % and iff the position of the vertex has not been fixed yet, add % another equation. Note that each arc enters twice (incoming % \emph{and} outgoing) in this procedure. Thus it is easiest to store % them \emph{both} ways in the |vlist| structure % (cf.~page~\pageref{pg:vconnect})\label{pg:vposition}. % \begin{macrocode} if unknown vlist[i]loc: origin = origin for j = varcs (i): + vlist[i]arc[j]tns * (vlist[i]loc - vlist[vlist[i]arc[j]]loc) endfor for j = vconstr (i): if i < vlist[i]constr[j]: + lambda[i][vlist[i]constr[j]] else: - lambda[vlist[i]constr[j]][i] fi endfor; fi endfor % \end{macrocode} % Inquiring minds might want to see the result in numbers: % \begin{macrocode} if vtracing: vdump; fi enddef; % % \end{macrocode} % \begin{macro}{\fmfposition} % Again, we can ask for positioning and drawing explicitely from \TeX % (usually called implicitely by |\end{fmfchar}|). This is useful for % subsequent fine tuning. % \begin{macrocode} % % \end{macrocode} % \end{macro} % Now we're done with the \MF{} macros % \begin{macrocode} %<*base> endinput; % % \end{macrocode} % and the \TeX{} macros too: % \begin{macrocode} %<*style> \mdqrestore % % \end{macrocode} % \Finale % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \appendix % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \section{Driver file} % \begin{macrocode} %<*driver> %<*!209> \documentclass[a4paper]{article} \usepackage{doc} % \end{macrocode} % The \MF{} and \MP{} logos come out much nicer if you have |mflogo| % installed: % \begin{macrocode} \IfFileExists{mflogo.sty}% {\usepackage{mflogo}% \def\FMF{\texttt{feyn}\textlogo{MF}}}% {\def\MF{\textsf{META}\-\textsf{FONT}}% \def\MP{\textsf{META}\-\textsf{POST}}% \def\FMF{\texttt{feyn}\textsf{MF}}} % \end{macrocode} % Here is the place to declare your own PostScript aware |dvi| driver % option: % \begin{macrocode} %\usepackage[dvips]{feynmp} %\usepackage{feynmf} % %<*209> %\documentstyle[doc,feynmp209]{article} %\documentstyle[doc,feynmf209]{article} \def\textit#1{{\it#1\/}} \def\textbf#1{{\bf#1}} \def\textsf#1{{\sf#1}} \def\texttt#1{{\tt#1}} \def\emph#1{{\em#1\/}} \let\bfseries\bf \def\LaTeXe{\LaTeX$2_\epsilon$} \def\MF{\textsf{META}\-\textsf{FONT}} \def\MP{\textsf{META}\-\textsf{POST}} \def\FMF{\texttt{feyn}\textsf{MF}} % \font\manfnt=manfnt \def\dangerousbend/{{\manfnt\char"7F}} \def\dubious{\begin{itemize}\item[\dangerousbend/]} \def\enddubious{\end{itemize}} \parindent0pt %\OnlyDescription \EnableCrossrefs \RecordChanges \CodelineIndex \DoNotIndex{\def,\gdef,\long,\let,\begin,\end,\if,\ifx,\else,\fi} \DoNotIndex{\immediate,\write,\newwrite,\openout,\closeout,\typeout} \DoNotIndex{\font,\nullfont,\jobname,\documentclass} \DoNotIndex{\batchmode,\errorstopmode,\char,\catcode,\ } \DoNotIndex{\CodelineIndex,\docdate,\DocInput,\DoNotIndex,\EnableCrossrefs} \DoNotIndex{\filedate,\filename,\fileversion,\logo,\manfnt} \DoNotIndex{\NeedsTeXFormat,\ProvidesPackage,\RecordChanges,\space} \DoNotIndex{\usepackage,\wlog,\@gobble,\@ifundefined,\@namedef,\@spaces} \DoNotIndex{\begingroup,\csname,\edef,\endcsname,\expandafter,\hbox} \DoNotIndex{\hskip,\ifeof,\ignorespaces,\item,\leavevmode,\loop,\makebox} \DoNotIndex{\newcounter,\newif,\newread,\openin,\par,\parindent,\put} \DoNotIndex{\read,\relax,\repeat,\setcounter,\stepcounter,\the} \DoNotIndex{\value,\vbox,\vskip} \DoNotIndex{} % \end{macrocode} % Cut the linebreaking some slack for macrocode which might conatin % long lines (it doesn't really hurt if they stick out a bit). % \begin{macrocode} \let\origmacrocode\macrocode \def\macrocode{\hfuzz 5em\origmacrocode} \begin{document} \DocInput{feynmf.dtx} \end{document} % % \end{macrocode} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \endinput Local Variables: mode:LaTeX fill-prefix:"% " indent-tabs-mode:nil change-log-default-name:"TODO" page-delimiter:"^% %%%%%%%%%*\n"